class NodeHandler(): ''' Description: The NodeHandler class is intended for generating and maintaining large numbers of Jenkins nodes from a csv file. Note: Need a method to compare current csv with existing nodes and do: Create / Updated / Delete accordingly Need means for auto launch jenkins node on slave host (server) after (device) nodes are created ''' def __init__(self): self.host = '' self.username = '' self.password = '' self.jenkins_node_config = 'config.xml' self.set_args() self.jenkins = Jenkins(self.host_url, self.username, self.password) self.elements = [] self.get_csv(self.node_list) if self.delete_all: for device in self.elements[1:]: self.delete(device) else: for device in self.elements[1:]: self.create(device) def set_args(self): parser = argparse.ArgumentParser(description='Script to manage Jenkins nodes') parser.add_argument('-s','--server', help="Enter server", required=True) parser.add_argument('-u','--username', help="Enter username", required=True) parser.add_argument('-p','--password', help="Enter password", required=True) parser.add_argument('-n','--node-list', help="Specify CSV file of nodes to be created/updated in bulk", default='devices.csv', required=False) parser.add_argument('-d','--delete-all', help="Flag all nodes in list for deletion", action='store_true', required=False) parser.add_argument('-c','--credentials-id', help="Enter CredentialsId (required for Web QA Jenkins)", default='xxxxxxxxx', required=False) args = vars(parser.parse_args()) # set any input values self.username = args['username'] self.password = args['password'] self.host = args['server'] self.host_url = 'http://{}/'.format(self.host) self.node_list = args['node_list'] self.delete_all = args['delete_all'] self.credentials_id = args['credentials_id'] def demo(self, name_job): print self.jenkins.version print self.jenkins.keys() # self.jenkinsenkins objects appear to be dict-like, mapping keys (job-names) to print self.jenkins[name_job] # print self.jenkins[name_job].get_last_good_build() def create(self, device): (dev_name, description, labels, node_host, port, dev_serial ) = device node_exists = self.jenkins.has_node(dev_name) if (node_exists): print 'Node: ' + dev_name + ' already exists.' node_status = 'existing' else: self.jenkins.create_node( name=dev_name, num_executors=1, node_description=description, remote_fs='/TBD', labels=labels, exclusive=False ) node_status = 'new' print 'Creating new node: ' + dev_name print 'Updating {} node '.format(node_status) self.post_config(device, self.jenkins_node_config) def delete(self, device): (dev_name, description, labels, node_host, port, dev_serial ) = device node_exists = self.jenkins.has_node(dev_name) if (node_exists): print 'Deleting node: ' + dev_name self.jenkins.delete_node(dev_name) else: print 'Node: {} does not exist.'.format(dev_name) def get_csv(self, filename): with open(filename) as f: data=[tuple(line) for line in csv.reader(f)] self.set_elements(data) def set_elements(self, elements): self.elements = elements def pretty_print(self, xml_string): root = etree.fromstring( xml_string ) return etree.tostring(root, pretty_print=True) def hydrate_template(self, jenkins_node_config, device): (dev_name, description, labels, node_host, port, dev_serial ) = device testvars = "b2g-" + dev_name + ".json" with open("config_JENKINS_WEB_QA.xml", "r") as file_template: xml_config = file_template.read() template = Template(xml_config) xml_config = template.substitute(dev_name=dev_name, description=description, labels=labels, node_host=node_host, port=port, dev_serial=dev_serial, testvars=testvars, credentials_id=self.credentials_id) try: fh = open(self.jenkins_node_config, "w") fh.write(xml_config) except IOError: print "Error: can\'t find file or read data" else: print "Jenkins node config.xml file created successfully" fh.close() print '-------------------------------------------' print xml_config print '-------------------------------------------' def get_url(self, device): (dev_name, description, labels, node_host, port, dev_serial ) = device url = 'http://' + \ self.username + ':' + self.password + '@' + \ self.host + '/computer/' + dev_name + '/' + self.jenkins_node_config url = 'http://' + self.host + '/computer/' + dev_name + '/' + self.jenkins_node_config return url def post_config(self, device, xml_filename): url = self.get_url(device) self.hydrate_template(xml_filename, device) print url headers = {'crumb':'c2eebfe9791555eb033019384dd261ee','crumbRequestField':'.crumb'} r = requests.post(url, data=open(xml_filename, 'rb'), headers=headers) print '---------------------------' print 'headers' print '---------------------------' print r.headers print '---------------------------' print(r.text)