def handle(event, _context): """Lambda Handler""" log_event(event) with ChefAPI(CHEF_SERVER_URL, get_pem(), USERNAME): instance_id = get_instance_id(event) try: search = Search('node', 'ec2_instance_id:' + instance_id) except ChefServerNotFoundError as err: LOGGER.error(err) return False if len(search) != 0: for instance in search: node = Node(instance.object.name) client = Client(instance.object.name) try: node.delete() LOGGER.info('===Node Delete: SUCCESS===') client.delete() LOGGER.info('===Client Delete: SUCCESS===') return True except ChefServerNotFoundError as err: LOGGER.error(err) return False else: LOGGER.info('=Instance does not appear to be Chef Server managed.=') return True
def computer_deleted(self, user, obj, computers=None): node_chef_id = obj.get('node_chef_id', None) if node_chef_id: api = get_chef_api(self.app.conf, user) node = Node(node_chef_id, api) node.delete() client = Client(node_chef_id, api=api) client.delete() self.log_action('deleted', 'Computer', obj)
def handle(event, _context): """Lambda Handler""" log_event(event) node_name = None node_ip = None # Remove from one of the chef servers for URL in CHEF_SERVER_URLS: with ChefAPI(URL, CHEF_PEM, CHEF_USERNAME): instance_id = get_instance_id(event) try: search = Search('node', 'ec2_instance_id:' + instance_id) except ChefServerNotFoundError as err: LOGGER.error(err) return False if len(search) != 0: for instance in search: node_name = instance.object.name node = Node(node_name) node_ip = node['ipaddress'] client = Client(node_name) try: node.delete() client.delete() LOGGER.info( '=====SUCCESSFULLY REMOVED INSTANCE FROM CHEF SERVER===== {}' .format(URL)) break except ChefServerNotFoundError as err: LOGGER.error(err) return False else: LOGGER.info( '===Instance does not appear to be Chef Server managed.=== {}' .format(URL)) # Remove from Spacewalk spacewalk_cleanup(node_ip) # Remove from DNS dns_cleanup(node_name) # Remove from AD active_directory_cleanup(node_name) # Remove fom Solarwinds solarwinds_cleanup(node_ip, node_name) # Remove from Chef Automate chef_automate_cleanup(node_name)
def destroy_node(self, node): """ Destroys chef node from openstack :param node: node to destroy :type node: ChefNode """ cnode = Node(node.name, node.environment.local_api) if cnode.exists: self.compute_client.servers.get(node['uuid']).delete() cnode.delete() client = Client(node.name, node.environment.local_api) if client.exists: client.delete()
def test_create(self): name = self.random() client = Client.create(name) self.register(client) self.assertEqual(client.name, name) #self.assertEqual(client.orgname, 'pycheftest') # See CHEF-2019 self.assertTrue(client.private_key) self.assertIn(name, Client.list()) client2 = Client(name) client2.rekey() self.assertNotEqual(client.private_key, client2.private_key)
def destroy_node(self, node): """ Destroys a node provisioned by razor :param node: Node to destroy :type node: ChefNode """ cnode = Node(node.name, node.environment.local_api) in_use = node['in_use'] if in_use == "provisioning" or in_use == 0: # Return to pool if the node is clean cnode['in_use'] = 0 cnode['archive'] = {} cnode.chef_environment = "_default" cnode.save() else: # Remove active model if the node is dirty active_model = cnode['razor_metadata']['razor_active_model_uuid'] try: if node.feature_in('controller'): # rabbit can cause the node to not actually reboot kill = ("for i in `ps -U rabbitmq | tail -n +2 | " "awk '{print $1}' `; do kill -9 $i; done") node.run_cmd(kill) node.run_cmd("shutdown -r now") self.api.remove_active_model(active_model) Client(node.name).delete() cnode.delete() sleep(15) except: util.logger.error("Node unreachable. " "Manual restart required:{0}".format( str(node)))
def _clean_client(self, hostid, config, target_system, **kwargs): """clean client""" from chef import Client try: client = Client( self._get_client_name( config['hostname'], config['clusterid'], target_system), api=self.api_) client.delete() logging.debug('client is removed for host %s ' 'config %s target_system %s', hostid, config, target_system) except Exception as error: logging.debug('no client to delete for host %s ' 'config %s target_system %s', hostid, config, target_system)
def _clean_client(self, hostid, config, target_system, **kwargs): """clean client""" from chef import Client try: client = Client(self._get_client_name(config['hostname'], config['clusterid'], target_system), api=self.api_) client.delete() logging.debug( 'client is removed for host %s ' 'config %s target_system %s', hostid, config, target_system) except Exception as error: logging.debug( 'no client to delete for host %s ' 'config %s target_system %s', hostid, config, target_system)
def post(self): node_id = self.request.POST.get('node_id') if node_id is None: return {'ok': False, 'message': 'Missing node ID'} settings = get_current_registry().settings api = get_chef_api(settings, self.request.user) # create chef client chef_client = ChefClient(node_id, api) if chef_client.exists: return {'ok': False, 'message': 'This client already exists'} chef_client = ChefClient.create(node_id, api) # Prepare the API for this client chef_url = settings.get('chef.url') chef_version = settings.get('chef.version') chef_ssl_verify = settings.get('chef.ssl.verify') if chef_ssl_verify == 'False' or chef_ssl_verify == 'True': chef_ssl_verify = bool(chef_ssl_verify) api = ChefAPI(chef_url, chef_client.private_key.encode(), node_id, chef_version, ssl_verify = False) # create chef node chef_node = ChefNode(node_id, api) if chef_node.exists: return {'ok': False, 'message': 'This node already exists'} chef_node.save() return {'ok': True, 'message': 'Node and client have been added', 'client_private_key': chef_client.private_key}
def post(self): node_id = self.request.POST.get('node_id') if node_id is None: return {'ok': False, 'message': 'Missing node ID'} settings = get_current_registry().settings api = get_chef_api(settings, self.request.user) # create chef client chef_client = ChefClient(node_id, api) if chef_client.exists: return {'ok': False, 'message': 'This client already exists'} chef_client = ChefClient.create(node_id, api) # Prepare the API for this client chef_url = settings.get('chef.url') chef_version = settings.get('chef.version') chef_ssl_verify = settings.get('chef.ssl.verify') if chef_ssl_verify == 'False' or chef_ssl_verify == 'True': chef_ssl_verify = bool(chef_ssl_verify) api = ChefAPI(chef_url, str(chef_client.private_key), node_id, chef_version, ssl_verify = False) # create chef node chef_node = ChefNode(node_id, api) if chef_node.exists: return {'ok': False, 'message': 'This node already exists'} chef_node.save() return {'ok': True, 'message': 'Node and client have been added', 'client_private_key': chef_client.private_key}
def test_get(self): client = Client('test_1') self.assertTrue(client.platform) self.assertEqual(client.orgname, 'pycheftest') self.assertTrue(client.public_key) self.assertTrue(client.certificate) self.assertEqual(client.private_key, None)
def put(self): # implements "knife client reregister" node_id = self.request.POST.get('node_id') if node_id is None: return {'ok': False, 'message': 'Missing node ID'} settings = get_current_registry().settings api = get_chef_api(settings, self.request.user) # remove current node's client chef_client = ChefClient(node_id, api) if not chef_client.exists: return {'ok': False, 'message': 'This client does not exists'} chef_client.rekey(api) return {'ok': True, 'message': "Chef node's client has been update", 'client_private_key': chef_client.private_key}
def delete(self): node_id = self.request.GET.get('node_id') if node_id is None: return {'ok': False, 'message': 'Missing node ID'} settings = get_current_registry().settings api = get_chef_api(settings, self.request.user) chef_node = ChefNode(node_id, api) if not chef_node.exists: return {'ok': False, 'message': 'This node does not exists'} chef_node.delete() chef_client = ChefClient(node_id, api) if not chef_client.exists: return {'ok': False, 'message': 'This client does not exists'} chef_client.delete() return {'ok': True, 'message': 'Node and client have been deleted'}
def create_chef_admin_user(api, settings, usrname, password=None): username = toChefUsername(usrname) if password is None: password = password_generator() data = {'name': username, 'password': password, 'admin': True} chef_user = api.api_request('POST', '/users', data=data) user_private_key = chef_user.get('private_key', None) if user_private_key: save_pem_for_username(settings, username, 'chef_user.pem', user_private_key) chef_client = Client.create(name=username, api=api, admin=True) client_private_key = getattr(chef_client, 'private_key', None) if client_private_key: save_pem_for_username(settings, username, 'chef_client.pem', client_private_key)
def setup(self, node_name, chef_server_url, client_key, prefix): self.clear_settings() # must at least check for black client_key because PyChef crashes # without exception on a blank client_key if not node_name or not chef_server_url or not client_key: return try: chef_api = ChefAPI( url=chef_server_url, key=client_key, client=node_name ) Client.list(api=chef_api) except: self._authenticated = False return self._authenticated = True self._api = chef_api self._bag_adapter = PrefixFilter(prefix)
def create_chef_admin_user(api, settings, usrname, password=None, email='*****@*****.**'): username = toChefUsername(usrname) if password is None: password = password_generator() if api.version_parsed >= pkg_resources.parse_version("12.0.0"): # Chef 12 user data data = {'name': username, 'password': password, 'admin': True, 'display_name': username, 'email': email} else: # Chef 11 user data data = {'name': username, 'password': password, 'admin': True} chef_user = api.api_request('POST', '/users', data=data) user_private_key = chef_user.get('private_key', None) if user_private_key: save_pem_for_username(settings, username, 'chef_user.pem', user_private_key) chef_client = Client.create(name=username, api=api, admin=True) client_private_key = getattr(chef_client, 'private_key', None) if client_private_key: save_pem_for_username(settings, username, 'chef_client.pem', client_private_key)
def test_list(self): self.assertIn('test_1', Client.list())
def test_delete(self): name = self.random() client = Client.create(name) client.delete() self.assertNotIn(name, Client.list())
def post(self): try: # Initialize report report = {'inserted': 0, 'updated': 0, 'total': 0, 'warnings': {}} objects_apply_policy = {'computer': [], 'user': []} db = self.request.db # Read GZIP data postedfile = self.request.POST['media'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() # Read XML data xmldoc = minidom.parseString(xmldata) # Get the root domain xmlDomain = xmldoc.getElementsByTagName('Domain')[0] is_ad_master = self.request.POST['master'] == 'True' domain = self._get_domain(self.importSchema[0], xmlDomain, is_ad_master, report) # Convert from AD objects to MongoDB objects mongoObjects = {} mongoObjectsPath = {} for objSchema in self.importSchema: objs = xmldoc.getElementsByTagName(objSchema['adName']) for adObj in objs: if not adObj.hasAttribute('ObjectGUID'): raise Exception('An Active Directory object must has "ObjectGUID" attrib.') mongoObject, is_saving = self._convertADObjectToMongoObject(domain, mongoObjects, objSchema, adObj, is_ad_master, report, objects_apply_policy) report['total'] += 1 if is_saving: mongoObjects[mongoObject['adDistinguishedName']] = mongoObject mongoObjectsPath[mongoObject['adDistinguishedName']] = mongoObject # Order mongoObjects by dependences if mongoObjects: mongoObjects[domain['adDistinguishedName']] = domain mongoObjectsPath[domain['adDistinguishedName']] = domain mongoObjects = self._orderByDependencesMongoObjects(mongoObjects, domain) # Save each MongoDB objects properRootDomainADDN = domain['adDistinguishedName'] for index, mongoObject in mongoObjects.items(): if index == properRootDomainADDN: continue # Get the proper path ("root,{0}._id,{1}._id,{2}._id...") listPath = re.findall(ur'([^, ]+=(?:(?:\\,)|[^,])+)', index) nodePath = ','.join(listPath[1:]) # Find parent mongoObjectParent = mongoObjectsPath[nodePath] mongoObjectParent = self.collection.find_one({'_id': mongoObjectParent['_id']}) path = '{0},{1}'.format(mongoObjectParent['path'], str(mongoObjectParent['_id'])) mongoObject['path'] = path # Save mongoObject self._saveMongoObject(mongoObject) # AD Fixes admin_user = self.request.user chef_server_api = get_chef_api(get_current_registry().settings, admin_user) if is_ad_master: for index, mongoObject in mongoObjects.items(): if mongoObject['type'] == 'group': if mongoObject['members'] != []: mongoObject['members'] = [] self._saveMongoObject(mongoObject) for index, mongoObject in mongoObjects.items(): updateMongoObject = False # MemberOf if mongoObject['type'] in ('user', 'computer'): if 'memberof' not in mongoObject or is_ad_master: mongoObject['memberof'] = [] if 'adPrimaryGroup' in mongoObject and mongoObject['adPrimaryGroup']: group = mongoObjects[mongoObject['adPrimaryGroup']] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[mongoObject['adPrimaryGroup']]['_id'] not in mongoObject['memberof']: mongoObject['memberof'].append(mongoObjects[mongoObject['adPrimaryGroup']]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adPrimaryGroup'] if 'adMemberOf' in mongoObject and mongoObject['adMemberOf']: for group_id in mongoObject['adMemberOf']: group = mongoObjects[group_id] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[group_id]['_id'] not in mongoObject['memberof']: mongoObject['memberof'].append(mongoObjects[group_id]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adMemberOf'] # Create Chef-Server Nodes if mongoObject['type'] == 'computer': chef_server_node = reserve_node_or_raise(mongoObject['name'], chef_server_api, 'gcc-ad-import-%s' % random.random(), attempts=3) ohai_gecos_in_runlist = self.RECIPE_NAME_OHAI_GECOS in chef_server_node.run_list gecos_ws_mgmt_in_runlist = self.RECIPE_NAME_GECOS_WS_MGMT in chef_server_node.run_list if not ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.append(self.RECIPE_NAME_OHAI_GECOS) chef_server_node.run_list.append(self.RECIPE_NAME_GECOS_WS_MGMT) elif not ohai_gecos_in_runlist and gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert(chef_server_node.run_list.index(self.RECIPE_NAME_GECOS_WS_MGMT), self.RECIPE_NAME_OHAI_GECOS) elif ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert(chef_server_node.run_list.index(self.RECIPE_NAME_OHAI_GECOS) + 1, self.RECIPE_NAME_GECOS_WS_MGMT) save_node_and_free(chef_server_node) chef_server_client = Client(mongoObject['name'], api=chef_server_api) if not chef_server_client.exists: chef_server_client.save() mongoObject['node_chef_id'] = mongoObject['name'] updateMongoObject = True # Save changes if updateMongoObject: self._saveMongoObject(mongoObject) # apply policies to new objects for node_type, node_names in objects_apply_policy.items(): nodes = self.collection.find({'name': {'$in': node_names}, 'path': get_filter_this_domain(domain), 'type': node_type}) for node in nodes: apply_policies_function = globals()['apply_policies_to_%s' % node['type']] apply_policies_function(self.collection, node, admin_user, api=chef_server_api) # Return result status = '{0} inserted, {1} updated of {2} objects imported successfully.'.format(report['inserted'], report['updated'], report['total']) response = {'status': status, 'ok': True} except Exception as e: logger.exception(e) response = {'status': u'{0}'.format(e), 'ok': False} warnings = report.get('warnings', []) if warnings: response['warnings'] = warnings return response
def post(self): try: # Initialize report report = {'inserted': 0, 'updated': 0, 'total': 0, 'warnings': {}} objects_apply_policy = {'computer': [], 'user': []} db = self.request.db # Read GZIP data postedfile = self.request.POST['media'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() # Read XML data xmldoc = minidom.parseString(xmldata) # Get the root domain xmlDomain = xmldoc.getElementsByTagName('Domain')[0] is_ad_master = self.request.POST['master'] == 'True' domain = self._get_domain(self.importSchema[0], xmlDomain, is_ad_master, report) # Convert from AD objects to MongoDB objects mongoObjects = {} mongoObjectsPath = {} for objSchema in self.importSchema: objs = xmldoc.getElementsByTagName(objSchema['adName']) for adObj in objs: if not adObj.hasAttribute('ObjectGUID'): raise Exception( 'An Active Directory object must has "ObjectGUID" attrib.' ) mongoObject, is_saving = self._convertADObjectToMongoObject( domain, mongoObjects, objSchema, adObj, is_ad_master, report, objects_apply_policy) report['total'] += 1 if is_saving: mongoObjects[ mongoObject['adDistinguishedName']] = mongoObject mongoObjectsPath[ mongoObject['adDistinguishedName']] = mongoObject # Order mongoObjects by dependences if mongoObjects: mongoObjects[domain['adDistinguishedName']] = domain mongoObjectsPath[domain['adDistinguishedName']] = domain mongoObjects = self._orderByDependencesMongoObjects( mongoObjects, domain) # Save each MongoDB objects properRootDomainADDN = domain['adDistinguishedName'] for index, mongoObject in mongoObjects.items(): if index == properRootDomainADDN: continue # Get the proper path ("root,{0}._id,{1}._id,{2}._id...") listPath = re.findall(ur'([^, ]+=(?:(?:\\,)|[^,])+)', index) nodePath = ','.join(listPath[1:]) # Find parent mongoObjectParent = mongoObjectsPath[nodePath] mongoObjectParent = self.collection.find_one( {'_id': mongoObjectParent['_id']}) path = '{0},{1}'.format(mongoObjectParent['path'], str(mongoObjectParent['_id'])) mongoObject['path'] = path # Save mongoObject self._saveMongoObject(mongoObject) # AD Fixes admin_user = self.request.user chef_server_api = get_chef_api(get_current_registry().settings, admin_user) if is_ad_master: for index, mongoObject in mongoObjects.items(): if mongoObject['type'] == 'group': if mongoObject['members'] != []: mongoObject['members'] = [] self._saveMongoObject(mongoObject) for index, mongoObject in mongoObjects.items(): updateMongoObject = False # MemberOf if mongoObject['type'] in ('user', 'computer'): if 'memberof' not in mongoObject or is_ad_master: mongoObject['memberof'] = [] if 'adPrimaryGroup' in mongoObject and mongoObject[ 'adPrimaryGroup']: group = mongoObjects[mongoObject['adPrimaryGroup']] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[mongoObject['adPrimaryGroup']][ '_id'] not in mongoObject['memberof']: mongoObject['memberof'].append(mongoObjects[ mongoObject['adPrimaryGroup']]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adPrimaryGroup'] if 'adMemberOf' in mongoObject and mongoObject[ 'adMemberOf']: for group_id in mongoObject['adMemberOf']: group = mongoObjects[group_id] if is_visible_group(db, group['_id'], mongoObject): if not mongoObject['_id'] in group['members']: group['members'].append(mongoObject['_id']) self._saveMongoObject(group) if mongoObjects[group_id][ '_id'] not in mongoObject['memberof']: mongoObject['memberof'].append( mongoObjects[group_id]['_id']) else: self._warningGroup(group, mongoObject, report) updateMongoObject = True del mongoObject['adMemberOf'] # Create Chef-Server Nodes if mongoObject['type'] == 'computer': chef_server_node = reserve_node_or_raise( mongoObject['name'], chef_server_api, 'gcc-ad-import-%s' % random.random(), attempts=3) ohai_gecos_in_runlist = self.RECIPE_NAME_OHAI_GECOS in chef_server_node.run_list gecos_ws_mgmt_in_runlist = self.RECIPE_NAME_GECOS_WS_MGMT in chef_server_node.run_list if not ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.append( self.RECIPE_NAME_OHAI_GECOS) chef_server_node.run_list.append( self.RECIPE_NAME_GECOS_WS_MGMT) elif not ohai_gecos_in_runlist and gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert( chef_server_node.run_list.index( self.RECIPE_NAME_GECOS_WS_MGMT), self.RECIPE_NAME_OHAI_GECOS) elif ohai_gecos_in_runlist and not gecos_ws_mgmt_in_runlist: chef_server_node.run_list.insert( chef_server_node.run_list.index( self.RECIPE_NAME_OHAI_GECOS) + 1, self.RECIPE_NAME_GECOS_WS_MGMT) save_node_and_free(chef_server_node) chef_server_client = Client(mongoObject['name'], api=chef_server_api) if not chef_server_client.exists: chef_server_client.save() mongoObject['node_chef_id'] = mongoObject['name'] updateMongoObject = True # Save changes if updateMongoObject: self._saveMongoObject(mongoObject) # apply policies to new objects for node_type, node_names in objects_apply_policy.items(): nodes = self.collection.find({ 'name': { '$in': node_names }, 'path': get_filter_this_domain(domain), 'type': node_type }) for node in nodes: apply_policies_function = globals()['apply_policies_to_%s' % node['type']] apply_policies_function(self.collection, node, admin_user, api=chef_server_api) # Return result status = '{0} inserted, {1} updated of {2} objects imported successfully.'.format( report['inserted'], report['updated'], report['total']) response = {'status': status, 'ok': True} except Exception as e: logger.exception(e) response = {'status': u'{0}'.format(e), 'ok': False} warnings = report.get('warnings', []) if warnings: response['warnings'] = warnings return response