def create(self): """ Handle user create operation. """ user_args = {} user_args['UserName'] = self.args.get("name", None) path = self.args.get("path", None) if path is not None: user_args['Path'] = path try: result = self.client.create_user(**user_args) metadata = result.get('ResponseMetadata') if metadata is not None: status = metadata.get('HTTPStatusCode') response = CommandResponse(status, result) logger.info("User created successfully") else: response = self.response_generator("No Response received.") except ClientError as e: response = self.response_generator(e) except Exception as ex: logger.info("Exception %s " % str(ex)) status = -1 if type(ex) == Strings.CONNECTION_ERROR: status = Status.SERVICE_UNAVAILABLE response = CommandResponse(status=status, msg=str(ex)) return response
def __init__(self, config_file_path): """ Initialize the object from a configuration file. @param config_file_path: Absolute path to configuration JSON file. @type config_file_path: str """ super(HalondRMQ, self).__init__(config_file_path) self._connection = None self._channel = None retry_counter = 1 while not(self._connection and self._channel) and retry_counter < 6: self.init_connection() if not (self._connection and self._channel): log.warning( 'RMQ Connection Failed. Retry Attempt: {} in {} secs'. format(retry_counter, retry_counter * 2 + 60)) time.sleep(retry_counter * 2 + 60) retry_counter += 1 if not(self._connection and self._channel): log.warning('RMQ connection Failed. Halon communication channel ' 'could not be established.') log.error('sspl_hl_resp channel creation FAILED. ' 'Retry attempts: 3') raise AMQPConnectionError() else: log.info('RMQ connection is Initialized.')
def response_generator(self, ex): """ Handle exception raised in all operations. It will return object with proper error code, which can be used in client to display proper error message. """ status = -1 command_output = "{}".format(str(ex)) try: logger.info("Error code %s " % ex.response['Error']['Code']) if ex.response['Error']['Code'] == Strings.INVALID_ACCESS_KEY: status = Status.UNAUTHORIZED elif ex.response['Error']['Code'] == Strings.ENTITY_EXISTS: status = Status.CONFLICT_STATUS elif ex.response['Error']['Code'] == Strings.NO_SUCH_ENTITY: status = Status.NOT_FOUND elif ex.response['Error']['Code'] == Strings.SIGNATURE_NOT_MATCH: status = Status.UNAUTHORIZED elif ex.response['Error']['Code'] == Strings.QUOTA_EXCEEDED: status = Status.BAD_REQUEST response = CommandResponse(status=status, msg=command_output) except Exception as ex: response = CommandResponse(status=status, msg=command_output) return response
def put_response_message(self, body): """ Read the request extract message_id and put the response message to file with file name as message_id. @param body: message body consumed from rabbit-mq queue @type body: str @param msg_dict: response messages dict @type msg_dict: dict """ log.info('Message received from sspl_hl_resp queue: {}'.format(body)) try: body_json = json.loads(body) except ValueError as mp_exception: log.info("Unable to parse message:{} IGNORE".format(mp_exception)) return message = body_json.get('message') if not message: log.info("Invalid Msg: message key is missing. Msg: {}".format( body_json)) return response_id = message.get("responseId") if not response_id: log.info( "Invalid Msg: response_id not found. Msg: {}".format(message)) return self.__message_dict[response_id] = message log.info("Updated message dict with:{}:{}".format( response_id, message))
def __init__(self, config_file_path): """ Initialize the object from a configuration file. @param config_file_path: Absolute path to configuration JSON file. @type config_file_path: str """ super(HalondPublisher, self).__init__(config_file_path) self.exchange = 'sspl_hl_cmd' self.routing_key = self.exchange log.info('RMQ Publisher config: {}'.format(self.__dict__)) self.declare_exchange_and_queue()
def get_station_node_info(self): """Extract the Station node information from halon_facts.yaml file""" try: parser = YamlParser(self.facts_file) except IOError as err: logger.warning('Could not read role_mapping_file.' ' Details: {}'.format(str(err))) logger.info('Trying default location: </etc/halon/{}>'.format( self.facts_file)) return 'DUMMY_FACTS_FILE' racks_info = parser.extract('id_racks') return self._search_station_rack_enclosure(racks_info).get('ip')
def declare_exchange_and_queue(self): """ Declares rabbitmq exchanges and queues """ try: self._channel.exchange_declare( exchange=self.exchange, type=self.exchange_type, auto_delete=False) log.info('Declared Exchange: {}, type: {}, auto_delete: {}' .format(self.exchange, self.exchange_type, False)) except AMQPError as err: log.warning('Exchange declaration Failed. Details: {}'.format( str(err) ))
def is_buckets_available(self, client): """ check if any buckets are associated with Account """ response = client.list_buckets() buckets = response['Buckets'] logger.info("Checking if buckets available %s " % buckets) for bucket in buckets: if bucket['Name'] is not None: logger.info("Buckets are associated with account") return True else: return False
def get_decision_logs_path(self): """Parse the decision logs path information from halon_role_mappings file""" try: parser = YamlParser(self.role_mapping_file) except IOError as err: logger.warning('Could not read role_mapping_file.' ' Details: {}'.format(str(err))) logger.info('Trying default location: </etc/halon/{}>'.format( self.role_mapping_file)) return '/etc/halon/{}'.format(self.role_mapping_file) role_info = parser.to_json() return self._search_logs_path(role_info)
def collect(self, bundle_name): # todo: collection info parameter should be added. """ Collect all the logs of the motr cluster system. @:param collection_info (YET TO BE ADDED ): json in the following format: {"message": "Could be reason for the collection", "time": "time_in_utc_format", "owner": "Default_for_now", "no_delete": "Indication to not delete this bundle", "name":"Same as the tar bar name" } """ logger.debug('Collection of bundle files has Started') self._ssu_list = self._cluster_node_manger.get_active_nodes() logger.info('SSU List : {}'.format(self._ssu_list)) bundle_dir_info = bundle_utils.get_bundle_dir_config( config.SUPPORT_BUNDLE_DIR_STRUCTURE, self._ssu_list, bundle_name ) logger.info('Bundle_dir_info : {}'.format(bundle_dir_info)) bundle_utils.create_bundle_structure( config.BASE_BUCKET_PATH, bundle_dir_info ) self._file_collection_rules = \ ClusterFilesCollectionRules(self._ssu_list, self._cluster_node_manger. get_cmu_hostname(), bundle_name) logger.info('Local Bundling Info: Bundle_id: {}, Collection_rule: {}'. format(bundle_name, self._file_collection_rules.get_local_files_info()) ) logger.info('Remote Bundling Info: Bundle_id: {}, Collection_rule: {}'. format(bundle_name, self._file_collection_rules.get_remote_files_info()) ) self.collect_files_from_cluster() SupportBundleHandler.build_tar_bundle(bundle_dir_info) logger.info('Collection of bundle files has Successfully completed. ' 'Bundle ID: {}'.format(bundle_name)) return 'success'
def list(self): """ Handles user list operation. """ user_args = {} try: logger.info("Inside list command") result = self.client.list_users(**user_args) metadata = result.get('ResponseMetadata') if metadata is not None: status = metadata.get('HTTPStatusCode') response = CommandResponse(status, result) else: response = self.response_generator("No Response received.") except Exception as ex: response = self.response_generator(ex) return response
def remove(self): """ Handle user remove operation. """ user_args = {} user_args['UserName'] = self.args.get("name", None) try: result = self.client.delete_user(**user_args) metadata = result.get('ResponseMetadata') if metadata is not None: status = metadata.get('HTTPStatusCode') response = CommandResponse(status, result) logger.info("User removed successfully") else: response = self.response_generator("No Response received.") except Exception as ex: response = self.response_generator(ex) return response
def create(self): """ Handles account creation operation. """ name = self.args.get("name", None) email = self.args.get("email", None) logger.info("Inside create command") parameters = {'Action': 'CreateAccount', 'AccountName': name, 'Email': email} try: response, data = execute_cmd(self.client, parameters) if response.status == Status.CREATED_STATUS: account_response = json.loads( json.dumps(xmltodict.parse(data))) account = \ account_response['CreateAccountResponse'][ 'CreateAccountResult'][ 'Account'] temp_account_response = CommandResponse( response.status, account) return temp_account_response else: logger.info("Status %s " % response.status) temp_account_response = CommandResponse(response.status, None) return temp_account_response except Exception as ex: logger.info("Exception %s " % str(ex)) status = -1 if type(ex) == Strings.CONNECTION_ERROR: status = Status.SERVICE_UNAVAILABLE temp_account_response = CommandResponse(status=status, msg=str(ex)) return temp_account_response
def publish_message(self, message): """ Publish the message to Halond Rabbit-MQ queue. @param message: message to be published to queue. @type message: str """ try: self._channel.basic_publish( exchange=self.exchange, routing_key=self.routing_key, body=json.dumps(message)) except AMQPError as err: log.warning( 'Message Publish Failed to Xchange: [{}], Key: [{}], Msg: {}. ' 'Details: {}'.format(self.exchange, self.routing_key, message, str(err))) else: log.info('Message Published to Xchange: [{}], Key: [{}], Msg: {}'. format(self.exchange, self.routing_key, message))
def __init__(self, config_file_path, callback_function): """ Initialize the object from a configuration file. @param config_file_path: Absolute path to configuration JSON file. @type config_file_path: str """ super(HalondConsumer, self).__init__(config_file_path) self.exchange = 'sspl_hl_resp' self.exchange_queue = self.exchange self.routing_key = self.exchange log.info('RMQ Consumer config: {}'.format(self.__dict__)) try: self._channel.exchange_declare(exchange=self.exchange, type=self.exchange_type) except AMQPError as err: log.warning('Exchange: [{}], type: [ {} ] cannot be declared.' ' Details: {}'.format(self.exchange, self.exchange_type, str(err))) try: self._channel.queue_declare(queue=self.exchange_queue, exclusive=False) self._channel.queue_bind(exchange=self.exchange, queue=self.exchange_queue, routing_key=self.routing_key) except AMQPError as err: log.error('Halon consumer Fails to initialize the queue.' 'Details: {}'.format(str(err))) raise log.info('Initialized Exchange: {}, Queue: {},' ' routing_key: {}'.format(self.exchange, self.exchange_queue, self.routing_key)) self._channel.basic_consume(lambda ch, method, properties, body: callback_function(body), queue=self.exchange_queue, no_ack=True)
def modify(self): """ Handle user modify operation. """ user_args = {} logger.info("Inside modify command") user_args['UserName'] = self.args.get("name", None) user_args['NewUserName'] = self.args.get("new_name", None) path = self.args.get("path", None) if path is not None: user_args['NewPath'] = path try: result = self.client.update_user(**user_args) metadata = result.get('ResponseMetadata') if metadata is not None: status = metadata.get('HTTPStatusCode') response = CommandResponse(status, result) logger.info("User modified successfully") else: response = self.response_generator("No Response received.") except ClientError as ex: response = self.response_generator(ex) return response
def remove(self): """ Handles Account remove operation :return: """ logger.info("Inside Remove command ") access_key = self.args.get("access_key", None) secret_key = self.args.get("secret_key", None) from sspl_hl.utils.s3admin.s3_utils import get_client s3_client, response = get_client(access_key, secret_key, Strings.S3_SERVICE) # First check if buckets are available for this account or not. logger.info("Check if buckets are associated with Account") try: if s3_client is None: # No S3 Client available. temp_account_response = CommandResponse(msg=response.msg, status=response.status) return temp_account_response else: is_bucket_avail = self.is_buckets_available(s3_client) if is_bucket_avail: status = -1 temp_account_response = CommandResponse( status=status, msg=Strings.BUCKETS_AVAILABLE_ERROR) return temp_account_response except Exception as ex: status = -1 command_output = "{}".format(str(ex)) try: logger.info("command_output %s " % command_output) if ex.response['Error']['Code'] == Strings.INVALID_ACCESS_KEY: status = Status.UNAUTHORIZED elif ex.response['Error']['Code'] \ == Strings.SERVICE_UNAVAILABLE: status = Status.SERVICE_UNAVAILABLE response = CommandResponse(status=status, msg=command_output) except Exception: response = CommandResponse(status=status, msg=command_output) return response # Buckets are not available. force = self.args.get("force", None) name = self.args.get("name", None) headers = {"content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} parameters = {'Action': 'DeleteAccount', 'AccountName': name} parameters['force'] = force auth_header = sign_request_v2(access_key, secret_key, 'POST', '/', {}, headers) headers['Authorization'] = auth_header try: response, data = execute_cmd(self.client, parameters, headers) logger.info("Account Remove response: [%s] " % response.status) if response.status == Status.OK_STATUS: account_response = json.loads( json.dumps(xmltodict.parse(data))) temp_account_response = CommandResponse( status=response.status) return temp_account_response else: account_response = json.loads( json.dumps(xmltodict.parse(data)))['ErrorResponse'] if account_response is None: temp_account_response = CommandResponse( response.status, None) return temp_account_response status = -1 if account_response['Error']['Code'] == \ Strings.NO_SUCH_ENTITY: status = Status.NOT_FOUND elif account_response['Error']['Code'] == \ Strings.SIGNATURE_NOT_MATCH: status = Status.UNAUTHORIZED elif account_response['Error']['Code'] == \ Strings.DELETE_CONFLICT: status = Status.CONFLICT_STATUS temp_account_response = CommandResponse(status=status) return temp_account_response except Exception as ex: logger.info("Exception %s " % str(ex)) status = -1 if type(ex) == Strings.CONNECTION_ERROR: status = Status.SERVICE_UNAVAILABLE temp_account_response = CommandResponse( status=status, msg=str(ex)) return temp_account_response