Index: umc/js/uvmm/CloudConnectionWizard.js =================================================================== --- umc/js/uvmm/CloudConnectionWizard.js (Revision 55163) +++ umc/js/uvmm/CloudConnectionWizard.js (Arbeitskopie) @@ -48,7 +48,11 @@ buildRendering: function() { this.pages.push({ name: 'pre_finish', - widgets: [] + widgets: [{ + name: 'dn', + type: TextBox, + visible: false + }] }); this.inherited(arguments); }, @@ -68,22 +72,22 @@ }, _testConnection: function(values) { - this.standby(true); - return tools.umcpCommand('uvmm/cloud/add', { + var dn = values.dn; + delete values.dn; + return this.standbyDuring(tools.umcpCommand('uvmm/cloud/add', { cloudtype: values.cloudtype, name: values.name, + dn: dn, testconnection: true, parameter: values }).then(lang.hitch(this, function(response) { this.moduleStore.onChange(); - this.standby(false); this.onFinished(response, values); }), lang.hitch(this, function(errormsg) { - this.standby(false); // show error message dialog.alert('Error: ' + errormsg); return 'general'; - })); + }))); }, next: function(currentPage) { Index: umc/js/uvmm/EC2.js =================================================================== --- umc/js/uvmm/EC2.js (Revision 55163) +++ umc/js/uvmm/EC2.js (Arbeitskopie) @@ -40,13 +40,13 @@ this.inherited(arguments); this.pages = [{ name: 'credentials', - headerText: _('Create a new cloud connection.'), + headerText: _('Cloud connection'), helpText: _('Please enter the corresponding credentials for the cloud connection. Use this link to get information about AWS credentials'), layout: [ 'name', 'region', 'access_id', - 'password', + 'password' ], widgets: [{ name: 'name', Index: umc/js/uvmm.js =================================================================== --- umc/js/uvmm.js (Revision 55163) +++ umc/js/uvmm.js (Arbeitskopie) @@ -258,25 +258,21 @@ // add a context menu to edit/delete items var menu = new Menu({}); - menu.addChild(new MenuItem({ + menu.addChild(this._menuEdit = new MenuItem({ label: _( 'Edit' ), iconClass: 'umcIconEdit', - onClick: lang.hitch(this, function(e) { - if(this._navContextItem) { - if(this._navContextItem.type == 'cloud' && this._navContextItem.dn) { - require('umc/app').openModule('udm', 'uvmm/cloudconnection',{'openObject': {'objectDN': this._navContextItem.dn, 'objectType': 'uvmm/cloudconnection'}}); - } else if(this._navContextItem.type == 'cloud' || (this._navContextItem.type == 'group' && this._navContextItem.id == 'cloudconnections')) { - require('umc/app').openModule('udm', 'uvmm/cloudconnection'); - } - } - })})); - /* menu.addChild(new MenuItem({ + onClick: lang.hitch(this, function() { + console.log(this._navContextItem.id); + this._editCloudConnection(this._navContextItem); + }) + })); + menu.addChild(this._menuDelete = new MenuItem({ label: _( 'Delete' ), iconClass: 'umcIconDelete', onClick: lang.hitch(this, function() { this.removeObjects(this._navContextItem.id); }) - }));*/ + })); menu.addChild(new MenuItem({ label: _( 'Reload' ), iconClass: 'umcIconRefresh', @@ -295,6 +291,7 @@ }), true)); this.own(aspect.before(menu, '_openMyself', lang.hitch(this, function() { this._navContextItem = this._navContextItemFocused; + this._updateMenuAvailability(); }))); // when we right-click anywhere on the tree, make sure we open the menu @@ -348,6 +345,14 @@ this._domainPage.on('UpdateProgress', lang.hitch(this, 'updateProgress')); }, + _updateMenuAvailability: function() { + var item = this._navContextItemFocused; + var canEdit = item.type == 'cloud' && item.dn; + var canDelete = canEdit; + this._menuEdit.set('disabled', !canEdit); + this._menuDelete.set('disabled', !canDelete); + }, + postCreate: function() { this.inherited(arguments); @@ -744,6 +749,20 @@ this.selectChild(wizard); }, + _editCloudConnection: function(item) { + var values = {cloudtype: item.cloudtype}; + this._addCloudConnection(values).then(lang.hitch(this, function(wizard) { + tools.forIn(wizard._pages, function(pageName, page) { + tools.forIn(item.params, function(key, value) { + var widget = wizard.getWidget(pageName, key); + if (widget) { + widget.set('value', value); + } + }); + }); + })); + }, + _addCloudConnection: function(values) { var wizard = null; @@ -786,7 +805,7 @@ tools.defer(wait, 1000); }); - this.loadWizardPages(values.cloudtype).then(lang.hitch(this, function(Wizard) { + return this.loadWizardPages(values.cloudtype).then(lang.hitch(this, function(Wizard) { wizard = new Wizard({ autoValidate: true, onFinished: _finished, @@ -797,6 +816,7 @@ }); this.addChild(wizard); this.selectChild(wizard); + return wizard; })); }, Index: umc/python/uvmm/cloud.py =================================================================== --- umc/python/uvmm/cloud.py (Revision 55163) +++ umc/python/uvmm/cloud.py (Arbeitskopie) @@ -36,8 +36,7 @@ from univention.management.console.log import MODULE from univention.management.console.modules.decorators import sanitize from univention.management.console.modules.sanitizers import SearchSanitizer, ChoicesSanitizer -from univention.uvmm.uvmm_ldap import ldap_cloud_types, ldap_cloud_connection_add -from subprocess import call +from univention.uvmm.uvmm_ldap import ldap_cloud_types, ldap_cloud_connection_add, ldap_cloud_connection_edit from notifier import Callback from urlparse import urldefrag @@ -87,6 +86,7 @@ 'cloudtype': d.cloudtype, 'available': d.available, 'last_error_message': d.last_error_message, + 'params': d.params, 'dn': d.dn, }) @@ -126,7 +126,10 @@ if success: # add cloud to ldap - ldap_cloud_connection_add(cloudtype, name, parameter) + if dn: + ldap_cloud_connection_edit(cloudtype, dn, name, parameter) + else: + ldap_cloud_connection_add(cloudtype, name, parameter) self.finished(request.id, data) else: @@ -143,18 +146,28 @@ name = request.options.get('name') testconnection = request.options.get('testconnection') parameter = request.options.get('parameter') + dn = request.options.get('dn') # add cloud to uvmm args = parameter args['name'] = name args['type'] = cloudtype - self.uvmm.send( - 'L_CLOUD_ADD', - Callback(_finished, request), - args=args, - testconnection=testconnection - ) + if dn: + self.uvmm.send( + 'L_CLOUD_EDIT', + Callback(_finished, request), + args=args, + dn=dn, + testconnection=testconnection + ) + else: + self.uvmm.send( + 'L_CLOUD_ADD', + Callback(_finished, request), + args=args, + testconnection=testconnection + ) def cloud_list_keypair(self, request): Index: src/univention/uvmm/cloudconnection.py =================================================================== --- src/univention/uvmm/cloudconnection.py (Revision 55163) +++ src/univention/uvmm/cloudconnection.py (Arbeitskopie) @@ -79,6 +79,7 @@ self.publicdata.last_update_try = -1 self.publicdata.available = False self.publicdata.last_error_message = "" + self.publicdata.params = cloud.copy() self._last_expensive_update = -1000000 self._instances = [] Index: src/univention/uvmm/cloudnode.py =================================================================== --- src/univention/uvmm/cloudnode.py (Revision 55163) +++ src/univention/uvmm/cloudnode.py (Arbeitskopie) @@ -133,10 +133,12 @@ def remove_connection(self, cloudname): """Remove connection; cloudname = ldap name attribute""" try: + connection = self.get(cloudname) del self[cloudname] except KeyError: raise CloudConnectionError("No Connection to %s present" % cloudname) logger.info("Removed connection to %s" % cloudname) + return connection def list_conn_instances(self, conn_name, pattern="*"): """ Index: src/univention/uvmm/commands.py =================================================================== --- src/univention/uvmm/commands.py (Revision 55163) +++ src/univention/uvmm/commands.py (Arbeitskopie) @@ -36,6 +36,8 @@ """ import copy +import ldap + import protocol import node import cloudnode @@ -70,6 +72,30 @@ raise CommandError('L_CLOUD_ADD', e) @staticmethod + def L_CLOUD_EDIT(server, request): + """ Edit cloud via libcloud """ + if not isinstance(request.dn, basestring): + raise CommandError('L_CLOUD_EDIT', _('dn != dict: %(dn)s'), dn=request.dn) + + if not isinstance(request.args, dict): + raise CommandError('L_CLOUD_EDIT', _('args != dict: %(args)s'), args=request.args) + + if not isinstance(request.testconnection, bool): + raise CommandError('L_CLOUD_EDIT', _('testconnection is not a bool %(testconnection)s'), testconnection=request.testconnection) + + logger.debug('L_CLOUD_EDIT %s %s, testconnection: %s' % (request.dn, request.args, request.testconnection)) + old_name = ldap.explode_dn(request.dn, 1)[0] + old_args = None + try: + old_connection = cloudnode.cloudconnections.remove_connection(old_name) + cloudnode.cloudconnections.add_connection(request.args, request.testconnection) + except cloudnode.CloudConnectionError, e: + if old_args is not None: + cloudnode.cloudconnections[old_name] = old_connection + #old_connection.connect(cloud, False) + raise CommandError('L_CLOUD_EDIT', e) + + @staticmethod def L_CLOUD_REMOVE(server, request): """ Remove cloud via libcloud """ if not isinstance(request.name, basestring): Index: src/univention/uvmm/protocol.py =================================================================== --- src/univention/uvmm/protocol.py (Revision 55163) +++ src/univention/uvmm/protocol.py (Arbeitskopie) @@ -278,6 +278,14 @@ self.args = None self.testconnection = True +class Request_L_CLOUD_EDIT(Request): + """Add libcloud cloud connection""" + def _default(self): + self.command = 'L_CLOUD_EDIT' + self.dn = None + self.args = None + self.testconnection = True + class Request_L_CLOUD_REMOVE(Request): """Remove libcloud cloud connection""" def _default(self): Index: src/univention/uvmm/uvmm_ldap.py =================================================================== --- src/univention/uvmm/uvmm_ldap.py (Revision 55163) +++ src/univention/uvmm/uvmm_ldap.py (Arbeitskopie) @@ -236,6 +236,26 @@ except LDAPError, e: raise LdapConnectionError(_('Could not open LDAP-Admin connection')) +def ldap_cloud_connection_edit(cloudtype, dn, name, parameter): + """ Modify an existing cloud connection.""" + try: + lo, position = univention.admin.uldap.getMachineConnection() + parameter_lst = [] + for k,v in parameter.items(): + if (k and v): + parameter_lst.append('%s=%s' % (k,v)) + attrs = { + 'objectClass': ['univentionVirtualMachineCloudConnection', 'univentionVirtualMachineHostOC', 'univentionObject'], + 'univentionObjectType': 'uvmm/cloudconnection', + 'cn': name, + 'univentionVirtualMachineCloudConnectionParameter': parameter_lst + } + modlist = [(k,None,v) for k,v in attrs.items()] + lo.modify(dn, modlist) + + except LDAPError: + raise LdapConnectionError(_('Could not open LDAP-Admin connection')) + def ldap_cloud_connection_add(cloudtype, name, parameter): """ Add a new cloud connection.""" try: