diff options
4 files changed, 140 insertions, 36 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 17afeb0c..018ab75f 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -397,4 +397,28 @@ public class GlusterDataModelManager { public List<VolumeOptionInfo> getVolumeOptionsDefaults() { return volumeOptionsDefaults; } + + public String getVolumeOptionDefaultValue(String optionKey) { + for(VolumeOptionInfo info : volumeOptionsDefaults) { + if(info.getName().equals(optionKey)) { + return info.getDefaultValue(); + } + } + throw new GlusterRuntimeException("Invalid option key [" + optionKey + + "] passed to GlusterDataModelManager#getVolumeOptionDefaultValue"); + } + + public void setAccessControlList(Volume volume, String accessControlList) { + volume.setAccessControlList(accessControlList); + setVolumeOption(volume, getOptionEntry(volume, Volume.OPTION_AUTH_ALLOW)); + } + + private Entry<String, String> getOptionEntry(Volume volume, String optionKey) { + for(Entry entry : volume.getOptions().entrySet()) { + if(entry.getKey().equals(optionKey)) { + return entry; + } + } + throw new GlusterRuntimeException("Couldn't find entry for option [" + optionKey + "] on volume [" + volume.getName()); + } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java index 054df413..50966920 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Volume.java @@ -49,7 +49,7 @@ public class Volume extends Entity { GLUSTERFS, NFS }; - private static final String OPTION_AUTH_ALLOW = "auth.allow"; + public static final String OPTION_AUTH_ALLOW = "auth.allow"; private static final String[] VOLUME_TYPE_STR = new String[] { "Plain Distribute", "Distributed Mirror", "Distributed Stripe" }; @@ -73,8 +73,8 @@ public class Volume extends Entity { // GlusterFS and NFS export is always enabled // Note: logic needs to make NFS optional - private Set<NAS_PROTOCOL> nasProtocols = new LinkedHashSet<NAS_PROTOCOL>( - Arrays.asList(new NAS_PROTOCOL[] { NAS_PROTOCOL.GLUSTERFS, NAS_PROTOCOL.NFS })); + private Set<NAS_PROTOCOL> nasProtocols = new LinkedHashSet<NAS_PROTOCOL>(Arrays.asList(new NAS_PROTOCOL[] { + NAS_PROTOCOL.GLUSTERFS, NAS_PROTOCOL.NFS })); private String accessControlList = "*"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java index 3d07e98f..274a1942 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java @@ -1,9 +1,15 @@ package com.gluster.storage.management.gui.views; import java.util.List; +import java.util.Map.Entry; + import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; @@ -20,6 +26,7 @@ import org.eclipse.ui.part.ViewPart; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Alert; import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Event; @@ -37,14 +44,16 @@ import com.gluster.storage.management.gui.utils.GUIHelper; public class VolumeSummaryView extends ViewPart { public static final String ID = VolumeSummaryView.class.getName(); private static final GUIHelper guiHelper = GUIHelper.getInstance(); - private static final String VOLUME_OPTION_AUTH_ALLOW = "auth.allow"; private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); private ScrolledForm form; private Volume volume; private CLabel lblStatusValue; private DefaultClusterListener volumeChangedListener; - + private Hyperlink changeLink; + private Text accessControlText; + private ControlDecoration errDecoration; + @Override public void createPartControl(Composite parent) { if (volume == null) { @@ -145,38 +154,25 @@ public class VolumeSummaryView extends ViewPart { private void createAccessControlField(Composite section) { toolkit.createLabel(section, "Access Control: ", SWT.NONE); - Text accessControlText = toolkit.createText(section, volume.getAccessControlList()); + accessControlText = toolkit.createText(section, volume.getAccessControlList()); + populateAccessControlText(); + addKeyListerForAccessControl(); accessControlText.setLayoutData(createDefaultLayoutData()); accessControlText.setEnabled(false); - createChangeLinkForAccessControl(section, accessControlText); + createChangeLinkForAccessControl(section); + + // error decoration used while validating the access control text + errDecoration = guiHelper.createErrorDecoration(accessControlText); + errDecoration.hide(); } - private void createChangeLinkForAccessControl(Composite section, final Text accessControlText) { - final Hyperlink changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); + private void createChangeLinkForAccessControl(Composite section) { + changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); changeLink.addHyperlinkListener(new HyperlinkAdapter() { @SuppressWarnings("static-access") private void finishEdit() { - - if (new ValidationUtil().isValidAccessControl(accessControlText.getText())) { - Status status = (new VolumesClient(GlusterDataModelManager.getInstance().getSecurityToken())) - .setVolumeOption(volume.getName(), VOLUME_OPTION_AUTH_ALLOW, accessControlText.getText()); - if (status.isSuccess()) { - volume.setAccessControlList(accessControlText.getText()); - accessControlText.setEnabled(false); - changeLink.setText("change"); - MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Access control", - status.getMessage()); - } else { - MessageDialog.openError(Display.getDefault().getActiveShell(), "Access control", - status.getMessage()); - } - - } else { - MessageDialog.openError(Display.getDefault().getActiveShell(), "Access control", - "Invalid IP / Host name "); - } - + saveAccessControlList(); } private void startEdit() { @@ -197,6 +193,64 @@ public class VolumeSummaryView extends ViewPart { }); } + private void saveAccessControlList() { + String newACL = accessControlText.getText(); + + if (!newACL.equals(volume.getAccessControlList()) && ValidationUtil.isValidAccessControl(newACL)) { + BusyIndicator.showWhile(Display.getDefault(), new Runnable() { + @Override + public void run() { + Status status = (new VolumesClient(GlusterDataModelManager.getInstance().getSecurityToken())) + .setVolumeOption(volume.getName(), Volume.OPTION_AUTH_ALLOW, accessControlText.getText()); + + if (status.isSuccess()) { + accessControlText.setEnabled(false); + changeLink.setText("change"); + + GlusterDataModelManager.getInstance().setAccessControlList(volume, accessControlText.getText()); + } else { + MessageDialog.openError(Display.getDefault().getActiveShell(), "Access control", + status.getMessage()); + } + } + }); + } else { + MessageDialog.openError(Display.getDefault().getActiveShell(), "Access control", + "Invalid IP / Host name "); + } + } + + private void addKeyListerForAccessControl() { + accessControlText.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent key) { + switch (key.keyCode) { + case SWT.ESC: + // Reset to default + populateAccessControlText(); + changeLink.setText("change"); + accessControlText.setEnabled(false); + break; + case 13: + // User has pressed enter. Save the new value + saveAccessControlList(); + break; + } + + validateAccessControlList(); + } + }); + } + + private void populateAccessControlText() { + String accessControlList = volume.getAccessControlList(); + if(accessControlList == null) { + // if not set, show default value + accessControlList = GlusterDataModelManager.getInstance().getVolumeOptionDefaultValue( + Volume.OPTION_AUTH_ALLOW); + } + accessControlText.setText(accessControlList); + } + private void createNASProtocolField(Composite section) { toolkit.createLabel(section, "NAS Protocols: ", SWT.NONE); @@ -219,8 +273,8 @@ public class VolumeSummaryView extends ViewPart { } private void createChangeLinkForNASProtocol(Composite section, final Button nfsCheckBox) { - final Hyperlink changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); - changeLink.addHyperlinkListener(new HyperlinkAdapter() { + final Hyperlink nasChangeLink = toolkit.createHyperlink(section, "change", SWT.NONE); + nasChangeLink.addHyperlinkListener(new HyperlinkAdapter() { private void finishEdit() { // TODO: Update value to back-end @@ -230,12 +284,12 @@ public class VolumeSummaryView extends ViewPart { volume.disableNFS(); } nfsCheckBox.setEnabled(false); - changeLink.setText("change"); + nasChangeLink.setText("change"); } private void startEdit() { nfsCheckBox.setEnabled(true); - changeLink.setText("update"); + nasChangeLink.setText("update"); } @Override @@ -308,4 +362,20 @@ public class VolumeSummaryView extends ViewPart { public void setFocus() { form.setFocus(); } + + private void validateAccessControlList() { + errDecoration.hide(); + + if (accessControlText.getText().length() == 0) { + errDecoration.setDescriptionText("Access control list cannot be empty!"); + errDecoration.show(); + return; + } + + if(!ValidationUtil.isValidAccessControl(accessControlText.getText())) { + errDecoration + .setDescriptionText("Access control list must be a comma separated list of IP addresses/Host names. Please enter a valid value!"); + errDecoration.show(); + } + } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java index ad724d25..d300c3b6 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java @@ -60,6 +60,7 @@ public class VolumeOptionsPage extends Composite { private TableViewer tableViewer; private GUIHelper guiHelper = GUIHelper.getInstance(); private Volume volume; + private DefaultClusterListener clusterListener; public enum OPTIONS_TABLE_COLUMN_INDICES { OPTION_KEY, OPTION_VALUE @@ -88,6 +89,14 @@ public class VolumeOptionsPage extends Composite { registerListeners(parent); } + /** + * @return + */ + private DefaultClusterListener createClusterListener() { + // TODO Auto-generated method stub + return null; + } + private void createAddButton() { addButton = toolkit.createButton(this, "&Add", SWT.FLAT); addButton.addSelectionListener(new SelectionAdapter() { @@ -117,6 +126,7 @@ public class VolumeOptionsPage extends Composite { private void registerListeners(final Composite parent) { addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { + GlusterDataModelManager.getInstance().removeClusterListener(clusterListener); toolkit.dispose(); } }); @@ -133,7 +143,7 @@ public class VolumeOptionsPage extends Composite { } }); - GlusterDataModelManager.getInstance().addClusterListener(new DefaultClusterListener() { + clusterListener = new DefaultClusterListener() { @Override public void volumeChanged(Volume volume, Event event) { super.volumeChanged(volume, event); @@ -151,8 +161,8 @@ public class VolumeOptionsPage extends Composite { } } } - }); - + }; + GlusterDataModelManager.getInstance().addClusterListener(clusterListener); } private void setupPageLayout() { |
