From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 6 Oct 2006 18:58:52 -0000 Subject: [Cluster-devel] conga/luci/site/luci/Extensions homebase_adapt ... Message-ID: <20061006185852.3524.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: conga Changes by: rmccabe at sourceware.org 2006-10-06 18:58:51 Modified files: luci/site/luci/Extensions: homebase_adapters.py cluster_adapters.py Log message: - enforce os homogeneity when deploying a cluster - allow 1 node clusters (used to require 2) - fix a few cases where code was returning a string instead of a list Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/homebase_adapters.py.diff?cvsroot=cluster&r1=1.22&r2=1.23 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.83&r2=1.84 --- conga/luci/site/luci/Extensions/homebase_adapters.py 2006/10/04 13:25:48 1.22 +++ conga/luci/site/luci/Extensions/homebase_adapters.py 2006/10/06 18:58:51 1.23 @@ -9,6 +9,7 @@ from ricci_defines import * from ricci_communicator import RicciCommunicator +from cluster_adapters import resolveOSType HOMEBASE_ADD_USER="1" HOMEBASE_ADD_SYSTEM="2" @@ -155,7 +156,7 @@ systemName = rc.system_name() except: error = 'Unable to establish a connection to the ricci agent on \"' + host + '\"' - return { 'host': host, 'ricci_host': systemName, 'errors': error, 'cur_auth': False } + return { 'host': host, 'ricci_host': systemName, 'errors': error, 'cur_auth': False, 'os': None } if rc.authed(): @@ -163,17 +164,21 @@ else: prevAuth = False if not passwd: - return { 'host': host, 'ricci_host': systemName, 'prev_auth': False, 'cur_auth': False } + return { 'host': host, 'ricci_host': systemName, 'prev_auth': False, 'cur_auth': False, 'os': None} else: try: rc.auth(passwd) except: pass if rc.authed(): + os_str = resolveOSType(rc.os()) + if os_str == None: + os_str = "rhel5" #Backup plan in case all is almost lost... + systemName = rc.system_name() if systemName[:9] == 'localhost' or systemName[:5] == '127.0': systemName = host - node = { 'host': host, 'ricci_host': systemName, 'prev_auth': prevAuth, 'cur_auth': True } + node = { 'host': host, 'ricci_host': systemName, 'prev_auth': prevAuth, 'cur_auth': True, 'os': os_str } cluster_info = rc.cluster_info() if cluster and ((not cluster_info) or (cluster_info[0] != cluster)): @@ -185,7 +190,7 @@ return node error = 'Unable to authenticate to the ricci agent on \"' + host + '\"' - return { 'host': host, 'ricci_host': systemName, 'prev_auth': False , 'cur_auth': False, 'errors': error } + return { 'host': host, 'ricci_host': systemName, 'prev_auth': False , 'cur_auth': False, 'errors': error, 'os': None } def validateAddClusterInitial(self, request): errors = list() @@ -1181,6 +1186,9 @@ # In case we want to give access to non-admin users in the future +def havePermCreateCluster(self): + return isAdmin(self) + def havePermAddStorage(self): return isAdmin(self) --- conga/luci/site/luci/Extensions/cluster_adapters.py 2006/10/04 16:20:22 1.83 +++ conga/luci/site/luci/Extensions/cluster_adapters.py 2006/10/06 18:58:51 1.84 @@ -25,7 +25,7 @@ #then only display chooser if the current user has #permissions on at least one. If the user is admin, show ALL clusters -from homebase_adapters import nodeAuth, nodeUnauth, manageCluster, createClusterSystems +from homebase_adapters import nodeAuth, nodeUnauth, manageCluster, createClusterSystems, havePermCreateCluster CLUSTER_FOLDER_PATH = '/luci/systems/cluster/' @@ -105,6 +105,9 @@ messages = list() requestResults = {} + if not havePermCreateCluster(self): + return (False, {'errors': ['You do not have sufficient rights to create a cluster.']}) + try: sessionData = request.SESSION.get('checkRet') except: @@ -119,8 +122,8 @@ except: return (False, { 'errors': ['Unknown number of systems entered'], 'requestResults': requestResults }) - if numStorage < 2: - return (False, { 'errors': ['A cluster must contain at least two nodes'], 'requestResults': requestResults }) + if numStorage < 1: + return (False, { 'errors': ['A cluster must contain at least one node'], 'requestResults': requestResults }) ret = validateClusterNodes(request, sessionData, clusterName, numStorage) errors.extend(ret[0]) @@ -128,22 +131,29 @@ try: nodeList = cluster_properties['nodeList'] - if len(nodeList) < 2: + if len(nodeList) < 1: + raise + except: + errors.append('A cluster must contain@least one node') + + try: + cluster_os = nodeList[0]['os'] + if not cluster_os: + raise + if len(filter(lambda x: x != cluster_os, nodeList[1:])) > 0: raise + except KeyError, e: + errors.append('Unable to identify the operating system running on the first cluster node.') + cluster_properties['isComplete'] = False except: - errors.append('A cluster must contain at least two nodes') + errors.append('Cluster nodes must be running compatible operating systems.') + cluster_properties['isComplete'] = False if cluster_properties['isComplete'] != True: nodeUnauth(nodeList) return (False, {'errors': errors, 'requestResults':cluster_properties }) if cluster_properties['isComplete'] == True: - from ricci_communicator import RicciCommunicator - rc = RicciCommunicator(nodeList[0]['ricci_host']) - os_str = resolveOSType(rc.os()) - if os_str == None: - os_str = "rhel5" #Backup plan in case all is almost lost... - batchNode = createClusterBatch(os_str, clusterName, clusterName, map(lambda x: x['ricci_host'], nodeList), True, False, False) if not batchNode: nodeUnauth(nodeList) @@ -298,23 +308,23 @@ else: mcast_val = 0 except KeyError, e: - return (False, {'errors': 'An invalid multicast selection was made.'}) + return (False, {'errors': ['An invalid multicast selection was made.']}) if not mcast_val: - return (True, {'messages': 'Changes accepted. - FILL ME IN'}) + return (True, {'messages': ['Changes accepted. - FILL ME IN']}) try: addr_str = form['mcast_addr'].strip() socket.inet_pton(socket.AF_INET, addr_str) except KeyError, e: - return (False, {'errors': 'No multicast address was given'}) + return (False, {'errors': ['No multicast address was given']}) except socket.error, e: try: socket.inet_pton(socket.AF_INET6, addr_str) except socket.error, e6: - return (False, {'errors': 'An invalid multicast address was given: ' + e}) + return (False, {'errors': ['An invalid multicast address was given: ' + e]}) - return (True, {'messages': 'Changes accepted. - FILL ME IN'}) + return (True, {'messages': ['Changes accepted. - FILL ME IN']}) def validateQDiskConfig(self, form): errors = list() @@ -328,10 +338,10 @@ else: qdisk_val = 0 except KeyError, e: - return (False, {'errors': 'An invalid quorum partition selection was made.'}) + return (False, {'errors': ['An invalid quorum partition selection was made.']}) if not qdisk_val: - return (True, {'messages': 'Changes accepted. - FILL ME IN'}) + return (True, {'messages': ['Changes accepted. - FILL ME IN']}) try: interval = int(form['interval']) @@ -436,7 +446,7 @@ if len(errors) > 0: return (False, {'errors': errors }) - return (True, {'messages': 'Changes accepted. - FILL ME IN'}) + return (True, {'messages': ['Changes accepted. - FILL ME IN']}) def validateGeneralConfig(self, form): errors = list() @@ -460,7 +470,7 @@ if len(errors) > 0: return (False, {'errors': errors}) - return (True, {'messages': 'Changes accepted. - FILL ME IN'}) + return (True, {'messages': ['Changes accepted. - FILL ME IN']}) def validateFenceConfig(self, form): errors = list() @@ -486,7 +496,7 @@ if len(errors) > 0: return (False, {'errors': errors }) - return (True, {'messages': 'Changes accepted. - FILL ME IN'}) + return (True, {'messages': ['Changes accepted. - FILL ME IN']}) configFormValidators = { 'general': validateGeneralConfig, @@ -500,11 +510,11 @@ messages = list() if not 'form' in request: - return (False, {'errors': 'No form was submitted.' }) + return (False, {'errors': ['No form was submitted.']}) if not 'configtype' in request.form: - return (False, {'errors': 'No configuration type was submitted.' }) + return (False, {'errors': ['No configuration type was submitted.']}) if not request.form['configtype'] in configFormValidators: - return (False, {'errors': 'An invalid configuration type was submitted.' }) + return (False, {'errors': ['An invalid configuration type was submitted.']}) val = configFormValidators[request.form['configtype']] ret = val(self, request.form) @@ -588,15 +598,17 @@ else: cldata['currentItem'] = False - cladd = {} - cladd['Title'] = "Create a New Cluster" - cladd['cfg_type'] = "clusteradd" - cladd['absolute_url'] = url + "?pagetype=" + CLUSTER_ADD - cladd['Description'] = "Create a Cluster" - if pagetype == CLUSTER_ADD: - cladd['currentItem'] = True - else: - cladd['currentItem'] = False + + if havePermCreateCluster(self): + cladd = {} + cladd['Title'] = "Create a New Cluster" + cladd['cfg_type'] = "clusteradd" + cladd['absolute_url'] = url + "?pagetype=" + CLUSTER_ADD + cladd['Description'] = "Create a Cluster" + if pagetype == CLUSTER_ADD: + cladd['currentItem'] = True + else: + cladd['currentItem'] = False clcfg = {} clcfg['Title'] = "Configure" @@ -2692,21 +2704,21 @@ def addResource(self, request, ragent): if not request.form: - return (False, {'errors': 'No form was submitted.'}) + return (False, {'errors': ['No form was submitted.']}) try: type = request.form['type'].strip() if not type or not type in resourceAddHandler: raise except: - return (False, {'errors': 'Form type is missing.'}) + return (False, {'errors': ['Form type is missing.']}) try: resname = request.form['resourceName'] except KeyError, e: # For IP, the IP address itself is the name. if request.form['type'] != 'ip': - return (False, {'errors': 'No resource name was given.'}) + return (False, {'errors': ['No resource name was given.']}) res = resourceAddHandler[type](request) modelb = request.SESSION.get('model')