AMBARI-20855 Removing unused script: relocate_host_components.py (Attila Magyar via adoroszlai)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2b146d9c Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2b146d9c Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2b146d9c Branch: refs/heads/branch-feature-AMBARI-12556 Commit: 2b146d9c421b12d2b11def840aca69d1dead4428 Parents: 34761fc Author: Attila Magyar <amag...@hortonworks.com> Authored: Tue May 2 17:34:26 2017 +0200 Committer: Attila Doroszlai <adorosz...@hortonworks.com> Committed: Tue May 2 17:34:26 2017 +0200 ---------------------------------------------------------------------- .../scripts/relocate_host_components.py | 489 ------------------- 1 file changed, 489 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/2b146d9c/ambari-server/src/main/resources/scripts/relocate_host_components.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/scripts/relocate_host_components.py b/ambari-server/src/main/resources/scripts/relocate_host_components.py deleted file mode 100644 index 1b9ad1e..0000000 --- a/ambari-server/src/main/resources/scripts/relocate_host_components.py +++ /dev/null @@ -1,489 +0,0 @@ -#!/usr/bin/env python - -''' -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -''' - -import optparse -import sys -import os -import logging -import tempfile -import urllib2 -import socket -import json -import base64 -import time - -AMBARI_HOSTNAME = None -AMBARI_PORT = 8080 -CLUSTER_NAME = None -PROTOCOL = "http" -USERNAME = "admin" -PASSWORD = "admin" -DEFAULT_TIMEOUT = 10 # seconds -START_ON_RELOCATE = False - -# Supported Actions -RELOCATE_ACTION = 'relocate' -ALLOWED_ACTUAL_STATES_FOR_RELOCATE = [ 'INIT', 'UNKNOWN', 'DISABLED', 'UNINSTALLED' ] -ALLOWED_HOST_STATUS_FOR_RELOCATE = [ 'HEALTHY' ] -STATUS_WAIT_TIMEOUT = 120 # seconds -STATUS_CHECK_INTERVAL = 10 # seconds - -# API calls -GET_CLUSTERS_URI = "/api/v1/clusters/" -GET_HOST_COMPONENTS_URI = "/api/v1/clusters/{0}/services/{1}/components/{2}" +\ - "?fields=host_components" -GET_HOST_COMPONENT_DESIRED_STATE_URI = "/api/v1/clusters/{0}/hosts/{1}" +\ - "/host_components/{2}" +\ - "?fields=HostRoles/desired_state" -GET_HOST_COMPONENT_STATE_URI = "/api/v1/clusters/{0}/hosts/{1}" +\ - "/host_components/{2}" +\ - "?fields=HostRoles/state" -GET_HOST_STATE_URL = "/api/v1/clusters/{0}/hosts/{1}?fields=Hosts/host_state" -HOST_COMPONENT_URI = "/api/v1/clusters/{0}/hosts/{1}/host_components/{2}" -ADD_HOST_COMPONENT_URI = "/api/v1/clusters/{0}/hosts?Hosts/host_name={1}" - -logger = logging.getLogger() - - - -class PreemptiveBasicAuthHandler(urllib2.BaseHandler): - - def __init__(self): - password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() - password_mgr.add_password(None, getUrl(''), USERNAME, PASSWORD) - self.passwd = password_mgr - self.add_password = self.passwd.add_password - - def http_request(self, req): - uri = req.get_full_url() - user = USERNAME - pw = PASSWORD - raw = "%s:%s" % (user, pw) - auth = 'Basic %s' % base64.b64encode(raw).strip() - req.add_unredirected_header('Authorization', auth) - return req - - -class AmbariResource: - - def __init__(self, serviceName, componentName): - self.serviveName = serviceName - self.componentName = componentName - self.isInitialized = False - - def initializeResource(self): - global CLUSTER_NAME - if CLUSTER_NAME is None: - CLUSTER_NAME = self.findClusterName() - - if self.serviveName is None: - raise Exception('Service name undefined') - - if self.componentName is None: - raise Exception('Component name undefined') - - handler = PreemptiveBasicAuthHandler() - opener = urllib2.build_opener(handler) - # Install opener for all requests - urllib2.install_opener(opener) - self.urlOpener = opener - - self.old_hostname = self.getHostname() - - self.isInitialized = True - - - def relocate(self, new_hostname): - if not self.isInitialized: - raise Exception('Resource not initialized') - - # If old and new hostname are the same exit harmlessly - if self.old_hostname == new_hostname: - logger.error('New hostname is same as existing host name, %s' % self.old_hostname) - sys.exit(2) - pass - - try: - self.verifyHostComponentStatus(self.old_hostname, new_hostname, self.componentName) - except Exception, e: - logger.error("Exception caught on verify relocate request.") - logger.error(e.message) - sys.exit(3) - - # Put host component in Maintenance state - self.updateHostComponentStatus(self.old_hostname, self.componentName, - "Disable", "DISABLED") - - # Delete current host component - self.deleteHostComponent(self.old_hostname, self.componentName) - - # Add component on the new host - self.addHostComponent(new_hostname, self.componentName) - - # Install host component - self.updateHostComponentStatus(new_hostname, self.componentName, - "Installing", "INSTALLED") - - # Wait on install - self.waitOnHostComponentUpdate(new_hostname, self.componentName, - "INSTALLED") - - if START_ON_RELOCATE: - # Start host component - self.updateHostComponentStatus(new_hostname, self.componentName, - "Starting", "STARTED") - - # Wait on start - self.waitOnHostComponentUpdate(new_hostname, self.componentName, "STARTED") - pass - pass - - def waitOnHostComponentUpdate(self, hostname, componentName, status): - logger.info("Waiting for host component status to update ...") - sleep_itr = 0 - state = None - while sleep_itr < STATUS_WAIT_TIMEOUT: - try: - state = self.getHostComponentState(hostname, componentName) - if status == state: - logger.info("Status update successful. status: %s" % state) - return - pass - except Exception, e: - logger.error("Caught an exception waiting for status update.. " - "continuing to wait...") - pass - - time.sleep(STATUS_CHECK_INTERVAL) - sleep_itr += STATUS_CHECK_INTERVAL - pass - if state and state != status: - logger.error("Timed out on wait, status unchanged. status = %s" % state) - sys.exit(1) - pass - pass - - def addHostComponent(self, hostname, componentName): - data = '{"host_components":[{"HostRoles":{"component_name":"%s"}}]}' % self.componentName - req = urllib2.Request(getUrl(ADD_HOST_COMPONENT_URI.format(CLUSTER_NAME, - hostname)), data) - - req.add_header("X-Requested-By", "ambari_probe") - req.get_method = lambda: 'POST' - try: - logger.info("Adding host component: %s" % req.get_full_url()) - resp = self.urlOpener.open(req) - self.logResponse('Add host component response: ', resp) - except Exception, e: - logger.error('Create host component failed, component: {0}, host: {1}' - .format(componentName, hostname)) - logger.error(e) - raise e - pass - - def deleteHostComponent(self, hostname, componentName): - req = urllib2.Request(getUrl(HOST_COMPONENT_URI.format(CLUSTER_NAME, - hostname, componentName))) - req.add_header("X-Requested-By", "ambari_probe") - req.get_method = lambda: 'DELETE' - try: - logger.info("Deleting host component: %s" % req.get_full_url()) - resp = self.urlOpener.open(req) - self.logResponse('Delete component response: ', resp) - except Exception, e: - logger.error('Delete {0} failed.'.format(componentName)) - logger.error(e) - raise e - pass - - def updateHostComponentStatus(self, hostname, componentName, contextStr, status): - # Update host component - data = '{"RequestInfo":{"context":"%s %s"},"Body":{"HostRoles":{"state":"%s"}}}' % (contextStr, self.componentName, status) - req = urllib2.Request(getUrl(HOST_COMPONENT_URI.format(CLUSTER_NAME, - hostname, componentName)), data) - req.add_header("X-Requested-By", "ambari_probe") - req.get_method = lambda: 'PUT' - try: - logger.info("%s host component: %s" % (contextStr, req.get_full_url())) - resp = self.urlOpener.open(req) - self.logResponse('Update host component response: ', resp) - except Exception, e: - logger.error('Update Status {0} failed.'.format(componentName)) - logger.error(e) - raise e - pass - - def verifyHostComponentStatus(self, old_hostname, new_hostname, componentName): - # Check desired state of host component is not STOPPED or host is - # unreachable - actualState = self.getHostComponentState(old_hostname, componentName) - - if actualState not in ALLOWED_ACTUAL_STATES_FOR_RELOCATE: - raise Exception('Aborting relocate action since host component ' - 'state is %s' % actualState) - - hostState = self.getHostSatus(new_hostname) - if hostState not in ALLOWED_HOST_STATUS_FOR_RELOCATE: - raise Exception('Aborting relocate action since host state is %s' % hostState) - - pass - - def getHostSatus(self, hostname): - hostStateUrl = getUrl(GET_HOST_STATE_URL.format(CLUSTER_NAME, hostname)) - - logger.info("Requesting host status: %s " % hostStateUrl) - urlResponse = self.urlOpener.open(hostStateUrl) - state = None - - if urlResponse: - response = urlResponse.read() - data = json.loads(response) - logger.debug('Response from getHostSatus: %s' % data) - if data: - try: - hostsInfo = data.get('Hosts') - if not hostsInfo: - raise Exception('Cannot find host state for host: {1}'.format(hostname)) - - state = hostsInfo.get('host_state') - except Exception, e: - logger.error('Unable to parse json data. %s' % data) - raise e - pass - - else: - logger.error("Unable to retrieve host state.") - pass - - return state - - - def getHostComponentState(self, hostname, componentName): - hostStatusUrl = getUrl(GET_HOST_COMPONENT_STATE_URI.format(CLUSTER_NAME, - hostname, componentName)) - - logger.info("Requesting host component state: %s " % hostStatusUrl) - urlResponse = self.urlOpener.open(hostStatusUrl) - state = None - - if urlResponse: - response = urlResponse.read() - data = json.loads(response) - logger.debug('Response from getHostComponentState: %s' % data) - if data: - try: - hostRoles = data.get('HostRoles') - if not hostRoles: - raise Exception('Cannot find host component state for component: ' +\ - '{0}, host: {1}'.format(componentName, hostname)) - - state = hostRoles.get('state') - except Exception, e: - logger.error('Unable to parse json data. %s' % data) - raise e - pass - - else: - logger.error("Unable to retrieve host component desired state.") - pass - - return state - - - # Log response for PUT, POST or DELETE - def logResponse(self, text=None, response=None): - if response is not None: - resp = str(response.getcode()) - if text is None: - text = 'Logging response from server: ' - if resp is not None: - logger.info(text + resp) - - def findClusterName(self): - clusterUrl = getUrl(GET_CLUSTERS_URI) - clusterName = None - - logger.info("Requesting clusters: " + clusterUrl) - urlResponse = self.urlOpener.open(clusterUrl) - if urlResponse is not None: - response = urlResponse.read() - data = json.loads(response) - logger.debug('Response from findClusterName: %s' % data) - if data: - try: - clusters = data.get('items') - if len(clusters) > 1: - raise Exception('Multiple clusters found. %s' % clusters) - - clusterName = clusters[0].get('Clusters').get('cluster_name') - except Exception, e: - logger.error('Unable to parse json data. %s' % data) - raise e - pass - else: - logger.error("Unable to retrieve clusters data.") - pass - - return clusterName - - def getHostname(self): - hostsUrl = getUrl(GET_HOST_COMPONENTS_URI.format(CLUSTER_NAME, - self.serviveName, self.componentName)) - - logger.info("Requesting host info: " + hostsUrl) - urlResponse = self.urlOpener.open(hostsUrl) - hostname = None - - if urlResponse is not None: - response = urlResponse.read() - data = json.loads(response) - logger.debug('Response from getHostname: %s' % data) - if data: - try: - hostRoles = data.get('host_components') - if not hostRoles: - raise Exception('Cannot find host component data for service: ' +\ - '{0}, component: {1}'.format(self.serviveName, self.componentName)) - if len(hostRoles) > 1: - raise Exception('More than one hosts found with the same role') - - hostname = hostRoles[0].get('HostRoles').get('host_name') - except Exception, e: - logger.error('Unable to parse json data. %s' % data) - raise e - pass - - else: - logger.error("Unable to retrieve host component data.") - pass - - return hostname - - -def getUrl(partial_url): - return PROTOCOL + "://" + AMBARI_HOSTNAME + ":" + AMBARI_PORT + partial_url - -def get_supported_actions(): - return [ RELOCATE_ACTION ] - -# -# Main. -# -def main(): - tempDir = tempfile.gettempdir() - outputFile = os.path.join(tempDir, "ambari_reinstall_probe.out") - - parser = optparse.OptionParser(usage="usage: %prog [options]") - parser.set_description('This python program is a Ambari thin client and ' - 'supports relocation of ambari host components on ' - 'Ambari managed clusters.') - - parser.add_option("-v", "--verbose", dest="verbose", action="store_false", - default=False, help="output verbosity.") - parser.add_option("-s", "--host", dest="server_hostname", - help="Ambari server host name.") - parser.add_option("-p", "--port", dest="server_port", - default="8080" ,help="Ambari server port. [default: 8080]") - parser.add_option("-r", "--protocol", dest="protocol", default = "http", - help="Protocol for communicating with Ambari server (" - "http/https) [default: http].") - parser.add_option("-c", "--cluster-name", dest="cluster_name", - help="Ambari cluster to operate on.") - parser.add_option("-e", "--service-name", dest="service_name", - help="Ambari Service to which the component belongs to.") - parser.add_option("-m", "--component-name", dest="component_name", - help="Ambari Service Component to operate on.") - parser.add_option("-n", "--new-host", dest="new_hostname", - help="New host to relocate the component to.") - parser.add_option("-a", "--action", dest="action", default = "relocate", - help="Script action. [default: relocate]") - parser.add_option("-o", "--output-file", dest="outputfile", - default = outputFile, metavar="FILE", - help="Output file. [default: %s]" % outputFile) - parser.add_option("-u", "--username", dest="username", - default="admin" ,help="Ambari server admin user. [default: admin]") - parser.add_option("-w", "--password", dest="password", - default="admin" ,help="Ambari server admin password.") - parser.add_option("-d", "--start-component", dest="start_component", - action="store_false", default=False, - help="Should the script start the component after relocate.") - - (options, args) = parser.parse_args() - - # set verbose - if options.verbose: - logging.basicConfig(level=logging.DEBUG) - else: - logging.basicConfig(level=logging.INFO) - - global AMBARI_HOSTNAME - AMBARI_HOSTNAME = options.server_hostname - - global AMBARI_PORT - AMBARI_PORT = options.server_port - - global CLUSTER_NAME - CLUSTER_NAME = options.cluster_name - - global PROTOCOL - PROTOCOL = options.protocol - - global USERNAME - USERNAME = options.username - - global PASSWORD - PASSWORD = options.password - - global START_ON_RELOCATE - START_ON_RELOCATE = options.start_component - - global logger - logger = logging.getLogger('AmbariProbe') - handler = logging.FileHandler(options.outputfile) - formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') - handler.setFormatter(formatter) - logger.addHandler(handler) - - action = RELOCATE_ACTION - - if options.action is not None: - if options.action not in get_supported_actions(): - logger.error("Unsupported action: " + options.action + ", " - "valid actions: " + str(get_supported_actions())) - sys.exit(1) - else: - action = options.action - - socket.setdefaulttimeout(DEFAULT_TIMEOUT) - - ambariResource = AmbariResource(serviceName=options.service_name, - componentName=options.component_name) - ambariResource.initializeResource() - - if action == RELOCATE_ACTION: - if options.new_hostname is not None: - ambariResource.relocate(options.new_hostname) - -if __name__ == "__main__": - try: - main() - except (KeyboardInterrupt, EOFError): - print("\nAborting ... Keyboard Interrupt.") - sys.exit(1)