Beispiel #1
0
class myjenkins:
	def __init__(self):
		self.server = Jenkins(jenkins_url,
		                      username=username,
		                      password=token_dict)

	def getjobconfig(self, job_name):
		job_info = self.server.get_job_config(job_name)
		return job_info

	# 根据给来的app id查询job的完整name,目前只看'0-Site'和'1-API'两个view下的,如果有需要可以加,需要保证这两个view下的所有job在view下都是唯一的
	def search_job_name(self, job_id):
		site = self.server.get_jobs(view_name='0-Site')
		web = self.server.get_jobs(view_name='1-API')
		b = site + web
		job_name = ''
		for i in b:
			w = re.findall(job_id, i['name'])
			if w != []:
				job_name = i['name']
		return job_name

	# 根据job的配置文件,找到他的git仓库地址,用于判断用户传入的分支名是否存在
	def get_git_url(self, job_name):
		info = self.getjobconfig(job_name)
		convertedDict = xmltodict.parse(info)
		git_repo_url = convertedDict['project']['scm']['userRemoteConfigs']['hudson.plugins.git.UserRemoteConfig'][
			'url']
		return git_repo_url
Beispiel #2
0
class JenkinsBot(BotPlugin):
    def __init__(self):
        self.jenkins = Jenkins(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD)

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.send(mess.getFrom(),
                  u'/me is getting the list of jobs from Jenkins... ',
                  message_type=mess.getType())

        search_term = args.strip().lower()
        jobs = [
            job for job in self.jenkins.get_jobs()
            if search_term.lower() in job['name'].lower()
        ]

        return self.format_jobs(jobs)

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.send(mess.getFrom(),
                  u'/me is getting the list of jobs from Jenkins... ',
                  message_type=mess.getType())

        jobs = [
            job for job in self.jenkins.get_jobs() if 'anime' in job['color']
        ]

        return self.format_running_jobs(jobs)

    def format_jobs(self, jobs):
        if len(jobs) == 0:
            return u'No jobs found.'

        max_length = max([len(job['name']) for job in jobs])
        return '\n'.join([
            '%s (%s)' % (job['name'].ljust(max_length), job['url'])
            for job in jobs
        ]).strip()

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return u'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join([
            '%s (%s)\n%s' % (job['name'], job['lastBuild']['url'],
                             job['healthReport'][0]['description'])
            for job in jobs_info
        ]).strip()
Beispiel #3
0
 def getjobs(self, msg, args):
     #server = self.get_server_instance()
     server = Jenkins(JENKINS_URL,
                      username=JENKINS_USERNAME,
                      password=JENKINS_PASSWORD)
     for j in server.get_jobs():
         jobs = server.get_job(j[0])
         return jobs.name
Beispiel #4
0
class JenkinsBot(BotPlugin):

    def __init__(self):
        self.jenkins = Jenkins(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD)

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.send(mess.getFrom(), u'/me is getting the list of jobs from Jenkins... ', message_type=mess.getType())

        search_term = args.strip().lower()
        jobs = [job for job in self.jenkins.get_jobs() if search_term.lower() in job['name'].lower()]

        return self.format_jobs(jobs)

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.send(mess.getFrom(), u'/me is getting the list of jobs from Jenkins... ', message_type=mess.getType())

        jobs = [job for job in self.jenkins.get_jobs() if 'anime' in job['color']]

        return self.format_running_jobs(jobs)

    def format_jobs(self, jobs):
        if len(jobs) == 0:
            return u'No jobs found.'

        max_length = max([len(job['name']) for job in jobs])
        return '\n'.join(['%s (%s)' % (job['name'].ljust(max_length), job['url']) for job in jobs]).strip()

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return u'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join(['%s (%s)\n%s' % (job['name'], job['lastBuild']['url'], job['healthReport'][0]['description']) for job in jobs_info]).strip()
Beispiel #5
0
    def check_running_job(self):
        #Check Running job
        j = Jenkins(appconfig.jenkins_url)
        job_list = j.get_jobs()
        job_queue_list = j.get_queue_info()
        running_job = []

        for job in job_list:
            if re.search('anime', job['color']):
                running_job.append(job['name'])

        for job_queue in job_queue_list:
            running_job.append(job_queue['task']['name'])

        return running_job
Beispiel #6
0
    def check_running_job(self):
        #Check Running job
        j = Jenkins(appconfig.jenkins_url)
        job_list = j.get_jobs()
        job_queue_list = j.get_queue_info()
        running_job = []

        for job in job_list:
            if re.search('anime', job['color']):
                running_job.append(job['name'])

        for job_queue in job_queue_list:
            running_job.append(job_queue['task']['name'])

        return running_job
Beispiel #7
0
def poll():
    jenkins = Jenkins(JENKINS_URL)
    while True:
        remote_jobs = jenkins.get_jobs()
        for remote in remote_jobs:
            for local in JOBS:
                if local['name'] == remote['name']:
                    led = local['led']
                    if remote['color'] == 'blue':
                        led.green(True)
                    elif remote['color'] == 'red':
                        led.red(True)
                    else:
                        if led.off():
                            led.yellow(True)
                        else:
                            led.off(True)
        time.sleep(1)
Beispiel #8
0
class JenkinsControl(object):
    war=pjoin(here, 'tmp/jenkins.war')
    cli=pjoin(here, 'tmp/jenkins-cli.jar')
    home=pjoin(here, 'tmp/jenkins')

    def __init__(self, addr='127.0.0.1:60888', cport='60887'):
        self.addr, self.port = addr.split(':')
        self.url = 'http://%s' % addr
        self.py = Jenkins(self.url)

    def start_server(self):
        cmd = pjoin(here, './bin/start-jenkins.sh 1>/dev/null 2>&1')
        env={'JENKINS_HOME'  : self.home,
             'JENKINS_PORT'  : self.port,
             'JENKINS_CPORT' : self.cport,
             'JENKINS_ADDR'  : self.addr}
        check_call(cmd, shell=True, env=env)

    def shutdown_server(self):
        cmd = 'echo 0 | nc %s %s' % (self.addr, self.cport)
        check_call(cmd, shell=True)

    def clean_home(self):
        rmtree(self.home)

    def createjob(self, name, configxml_fn):
        self.py.create_job(name, open(configxml_fn).read())

    def getjobs(self):
        return {i['name'] : i for i in self.py.get_jobs()}

    def enabled(self, name):
       return self.py.get_job_info(name)['buildable']

    def job_etree(self, job):
        res = self.py.get_job_config(job)
        res = etree.fromstring(res)
        return res
Beispiel #9
0
class JenkinsBot(BotPlugin):
    """Basic Err integration with Jenkins CI"""

    min_err_version = '1.2.1'
    # max_err_version = '4.0.3'

    def get_configuration_template(self):
        return CONFIG_TEMPLATE

    def configure(self, configuration):
        if configuration is not None and configuration != {}:
            config = dict(chain(CONFIG_TEMPLATE.items(),
                                configuration.items()))
        else:
            config = CONFIG_TEMPLATE
        super(JenkinsBot, self).configure(config)
        return

    def check_configuration(self, configuration):
        self.log.debug(configuration)
        for c, v in configuration.items():
            if c == 'URL':
                if not validators.url(v):
                    raise ValidationException('JENKINS_URL is not a well formed URL')
            elif c in ['USERNAME', 'PASSWORD', 'RECEIVE_NOTIFICATION']:
                if len(v) == 0 or not isinstance(v, str):
                    raise ValidationException("{} is a required string config setting".format(c))
            elif c in ['CHATROOMS_NOTIFICATION']:
                if not isinstance(v, tuple):
                    raise ValidationException("{} should be of type tuple".format(c))
        return

    def connect_to_jenkins(self):
        """Connect to a Jenkins instance using configuration."""
        self.log.debug('Connecting to Jenkins ({0})'.format(
            self.config['URL']))
        self.jenkins = Jenkins(url=self.config['URL'],
                               username=self.config['USERNAME'],
                               password=self.config['PASSWORD'])
        return

    def broadcast(self, mess):
        """Shortcut to broadcast a message to all elligible chatrooms."""
        chatrooms = (self.config['CHATROOMS_NOTIFICATION']
                     if self.config['CHATROOMS_NOTIFICATION']
                     else self.bot_config.CHATROOM_PRESENCE)

        for room in chatrooms:
            self.send(self.build_identifier(room), mess)
        return

    @webhook(r'/jenkins/notification')
    def handle_notification(self, incoming_request):
        if not self.config['RECEIVE_NOTIFICATION']:
            return 'Notification handling is disabled.'

        self.log.debug(repr(incoming_request))
        self.broadcast(self.format_notification(incoming_request))
        return

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.connect_to_jenkins()
        return self.format_jobs([job for job in self.jenkins.get_jobs(folder_depth=None)
            if args.lower() in job['fullname'].lower()])

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.connect_to_jenkins()

        jobs = [job for job in self.jenkins.get_jobs()
                if 'anime' in job['color']]
        return self.format_running_jobs(jobs)

    @botcmd(split_args_with=None)
    def jenkins_param(self, mess, args):
        """List Parameters for a given job."""
        if len(args) == 0:
            return 'What Job would you like the parameters for?'

        self.connect_to_jenkins()

        job = self.jenkins.get_job_info(args[0])
        if job['actions'][1] != {}:
            job_param = job['actions'][1]['parameterDefinitions']
        elif job['actions'][0] != {}:
            job_param = job['actions'][0]['parameterDefinitions']
        else:
            job_param = []

        return self.format_params(job_param)

    @botcmd(split_args_with=None)
    def jenkins_build(self, mess, args):
        """Build a Jenkins Job with the given parameters
        Example: !jenkins build test_project FOO:bar
        """
        if len(args) == 0:  # No Job name
            return 'What job would you like to build?'

        self.connect_to_jenkins()
        params = self.build_parameters(args[1:])

        # Is it a parameterized job ?
        job = self.jenkins.get_job_info(args[0])
        if job['actions'][0] == {} and job['actions'][1] == {}:
            self.jenkins.build_job(args[0])
        else:
            self.jenkins.build_job(args[0], params)

        running_job = self.search_job(args[0])
        return 'Your job should begin shortly: {0}'.format(
            self.format_jobs(running_job))

    @botcmd(split_args_with=None)
    def build(self, mess, args):
        """Shortcut for jenkins_build"""
        return self.jenkins_build(mess, args)

    @botcmd
    def jenkins_unqueue(self, msg, args):
        """Cancel a queued job.
        Example !jenkins unqueue foo
        """
        self.connect_to_jenkins()

        try:
            queue = self.jenkins.get_queue_info()

            job = next((job for job in queue if job['task']['name'].lower() == args.lower()), None)

            if job:
                self.jenkins.cancel_queue(job['id'])
                return 'Unqueued job {0}'.format(job['task']['name'])
            else:
                return 'Could not find job {0}, but found the following: {1}'.format(
                    args, ', '.join(job['task']['name'] for job in queue))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

    @botcmd(split_args_with=None)
    def jenkins_createjob(self, mess, args):
        """Create a Jenkins Job.
        Example: !jenkins createjob pipeline foo [email protected]:foo/bar.git
        """
        if len(args) < 2:  # No Job type or name
            return 'Oops, I need a type and a name for your new job.'

        if args[0] not in ('pipeline', 'multibranch'):
            return 'I\'m sorry, I can only create `pipeline` and \
                    `multibranch` jobs.'

        self.connect_to_jenkins()

        try:
            if args[0] == 'pipeline':
                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_PIPELINE.format(repository=args[2]))

            elif args[0] == 'multibranch':
                repository = args[2].rsplit('/', maxsplit=2)[-2:]

                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_MULTIBRANCH.format(
                        repo_owner=repository[0].split(':')[-1],
                        repo_name=repository[1].strip('.git')))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)
        return 'Your job has been created: {0}/job/{1}'.format(
            self.config['URL'], args[1])

    @botcmd(split_args_with=None)
    def jenkins_deletejob(self, mess, args):
        """Delete a Jenkins Job.
        Example: !jenkins deletejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablejob(self, mess, args):
        """Enable a Jenkins Job.
        Example: !jenkins enablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablejob(self, mess, args):
        """Disable a Jenkins Job.
        Example: !jenkins disablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been disabled.'

    @botcmd(split_args_with=None)
    def jenkins_createnode(self, mess, args):
        """Create a Jenkins Node with a JNLP Launcher with optionnal labels.
        Example: !jenkins createnode runner-foo-laptop /home/foo # without labels
        Example: !jenkins createnode runner-bar-laptop /home/bar linux docker # with labels
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need a name and a working dir for your new node.'

        self.connect_to_jenkins()

        try:
            self.jenkins.create_node(
                name=args[0],
                remoteFS=args[1],
                labels=' '.join(args[2:]),
                exclusive=True,
                launcher=LAUNCHER_JNLP)
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been created: {0}/computer/{1}'.format(
            self.config['URL'], args[0])

    @botcmd(split_args_with=None)
    def jenkins_deletenode(self, mess, args):
        """Delete a Jenkins Node.
        Example: !jenkins deletenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablenode(self, mess, args):
        """Enable a Jenkins Node.
        Example: !jenkins enablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablenode(self, mess, args):
        """Disable a Jenkins Node.
        Example: !jenkins disablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been disabled.'

    def search_job(self, search_term):
        self.log.debug('Querying Jenkins for job "{0}"'.format(search_term))
        return [job for job in self.jenkins.get_jobs(folder_depth=None)
                if search_term.lower() == job['fullname'].lower()]

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return 'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join(['%s (%s)\n%s' % (
            job['name'],
            job['lastBuild']['url'],
            job['healthReport'][0]['description'])
                            for job in jobs_info]).strip()

    @staticmethod
    def format_jobs(jobs):
        if len(jobs) == 0:
            return 'No jobs found.'

        max_length = max([len(job['fullname']) for job in jobs])
        return '\n'.join(
            ['%s (%s)' % (job['fullname'].ljust(max_length), job['url'])
             for job in jobs]).strip()

    @staticmethod
    def format_params(job):
        """Format job parameters."""
        if len(job) == 0:
            return 'This job is not parameterized.'
        PARAM_TEMPLATE = Template("""{% for p in params %}Type: {{p.type}}
Description: {{p.description}}
Default Value: {{p.defaultParameterValue.value}}
Parameter Name: {{p.name}}

{% endfor %}""")
        return PARAM_TEMPLATE.render({'params': job})

    @staticmethod
    def format_notification(body):
        body['fullname'] = body.get('fullname', body['name'])
        NOTIFICATION_TEMPLATE = Template("""Build #{{build.number}} \
{{build.status}} for Job {{fullname}} ({{build.full_url}})
{% if build.scm %}Based on {{build.scm.url}}/commit/{{build.scm.commit}} \
({{build.scm.branch}}){% endif %}""")
        return NOTIFICATION_TEMPLATE.render(body)

    @staticmethod
    def build_parameters(params):
        if len(params) > 0:
            return {param.split(':')[0]: param.split(':')[1]
                    for param in params}
        return {'': ''}
Beispiel #10
0
 def get_jobs(self):
     j = Jenkins(self.hostname, self.username, self.api_key)
     jobs = j.get_jobs()
     return jobs
Beispiel #11
0
class JenkinsBot(BotPlugin):

    def connect_to_jenkins(self):
        self.jenkins = Jenkins(JENKINS_URL, username=JENKINS_USERNAME, password=JENKINS_PASSWORD)

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.connect_to_jenkins()

        search_term = args.strip().lower()
        jobs = self.search_job(search_term)
        
        return self.format_jobs(jobs)


    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.connect_to_jenkins()

        jobs = [job for job in self.jenkins.get_jobs() if 'anime' in job['color']]

        return self.format_running_jobs(jobs)


    @botcmd
    def jenkins_param(self, mess, args):
        """List Parameters for a given job."""
        self.connect_to_jenkins()
        
        if len(args) == 0:
            return u'What Job would you like the parameters for?'
        if len(args.split()) > 1:
            return u'Please enter only one Job Name'

        if self.jenkins.get_job_info(args)['actions'][0] == {}:
            job_param = self.jenkins.get_job_info(args)['actions'][1]['parameterDefinitions']
        else:
            job_param = self.jenkins.get_job_info(args)['actions'][0]['parameterDefinitions']

        return self.format_params(job_param)


    @botcmd(split_args_with=None)
    def jenkins_build(self, mess, args):
        """Build a Jenkins Job with the given parameters
        Example: !jenkins build test_project FOO:bar
        """
        self.connect_to_jenkins()

        if len(args) == 0:
            return u'What job would you like to build?'

        parameters = self.build_parameters(args[1:])
        self.jenkins.build_job(args[0], parameters)
        running_job = self.search_job(args[0])
        
        return 'Your job should begin shortly: {0}'.format(self.format_jobs(running_job))


    def search_job(self, search_term):
        return [job for job in self.jenkins.get_jobs() if search_term.lower() in job['name'].lower()]


    def format_jobs(self, jobs):
        if len(jobs) == 0:
            return u'No jobs found.'

        max_length = max([len(job['name']) for job in jobs])
        return '\n'.join(['%s (%s)' % (job['name'].ljust(max_length), job['url']) for job in jobs]).strip()


    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return u'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join(['%s (%s)\n%s' % (job['name'], job['lastBuild']['url'], job['healthReport'][0]['description']) for job in jobs_info]).strip()


    def format_params(self, job):
        parameters = ''

        for param in range (0, len(job)):
            parameters = parameters + ("Type: {0}\nDescription: {1}\nDefault Value: {2}\nParameter Name: {3}\n_\n"
                .format(job[param]['type'], job[param]['description'], str(job[param]['defaultParameterValue']['value']), job[param]['name']))

        return parameters


    def build_parameters(self, params):
        if len(params) == 0:
            return ast.literal_eval("{'':''}")

        parameters_list = "{'"

        for counter, param in enumerate(params):
            param = param.split(':')
            if counter < len(params) - 1:
                parameters_list = parameters_list + param[0] + "': '" + param[1] + "', '"
            else:
                parameters_list = parameters_list + param[0] + "': '" + param[1] + "'"

        parameters_list = parameters_list + '}'

        return ast.literal_eval(parameters_list)
Beispiel #12
0
class JenkinsBot(BotPlugin):
    """Basic Err integration with Jenkins CI"""

    min_err_version = '1.2.1'

    # max_err_version = '4.0.3'

    def get_configuration_template(self):
        return CONFIG_TEMPLATE

    def configure(self, configuration):
        if configuration is not None and configuration != {}:
            config = dict(chain(CONFIG_TEMPLATE.items(),
                                configuration.items()))
        else:
            config = CONFIG_TEMPLATE
        super(JenkinsBot, self).configure(config)
        return

    def check_configuration(self, configuration):
        self.log.debug(configuration)
        for c, v in configuration.items():
            if c == 'URL':
                if not validators.url(v):
                    raise ValidationException(
                        'JENKINS_URL is not a well formed URL')
            elif c in ['USERNAME', 'PASSWORD', 'RECEIVE_NOTIFICATION']:
                if len(v) == 0 or not isinstance(v, str):
                    raise ValidationException(
                        "{} is a required string config setting".format(c))
            elif c in ['CHATROOMS_NOTIFICATION']:
                if not isinstance(v, tuple):
                    raise ValidationException(
                        "{} should be of type tuple".format(c))
        return

    def connect_to_jenkins(self):
        """Connect to a Jenkins instance using configuration."""
        self.log.debug('Connecting to Jenkins ({0})'.format(
            self.config['URL']))
        self.jenkins = Jenkins(url=self.config['URL'],
                               username=self.config['USERNAME'],
                               password=self.config['PASSWORD'])
        return

    def broadcast(self, mess):
        """Shortcut to broadcast a message to all elligible chatrooms."""
        chatrooms = (self.config['CHATROOMS_NOTIFICATION']
                     if self.config['CHATROOMS_NOTIFICATION'] else
                     self.bot_config.CHATROOM_PRESENCE)

        for room in chatrooms:
            self.send(self.build_identifier(room), mess)
        return

    @webhook(r'/jenkins/notification')
    def handle_notification(self, incoming_request):
        if not self.config['RECEIVE_NOTIFICATION']:
            return 'Notification handling is disabled.'

        self.log.debug(repr(incoming_request))
        self.broadcast(self.format_notification(incoming_request))
        return

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.connect_to_jenkins()
        return self.format_jobs([
            job for job in self.jenkins.get_jobs(folder_depth=None)
            if args.lower() in job['fullname'].lower()
        ])

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.connect_to_jenkins()

        jobs = [
            job for job in self.jenkins.get_jobs() if 'anime' in job['color']
        ]
        return self.format_running_jobs(jobs)

    @botcmd(split_args_with=None)
    def jenkins_param(self, mess, args):
        """List Parameters for a given job."""
        if len(args) == 0:
            return 'What Job would you like the parameters for?'

        self.connect_to_jenkins()

        job = self.jenkins.get_job_info(args[0])
        if job['actions'][1] != {}:
            job_param = job['actions'][1]['parameterDefinitions']
        elif job['actions'][0] != {}:
            job_param = job['actions'][0]['parameterDefinitions']
        else:
            job_param = []

        return self.format_params(job_param)

    @botcmd(split_args_with=None)
    def jenkins_build(self, mess, args):
        """Build a Jenkins Job with the given parameters
        Example: !jenkins build test_project FOO:bar
        """
        if len(args) == 0:  # No Job name
            return 'What job would you like to build?'

        self.connect_to_jenkins()
        params = self.build_parameters(args[1:])

        # Is it a parameterized job ?
        job = self.jenkins.get_job_info(args[0])
        if job['actions'][0] == {} and job['actions'][1] == {}:
            self.jenkins.build_job(args[0])
        else:
            self.jenkins.build_job(args[0], params)

        running_job = self.search_job(args[0])
        return 'Your job should begin shortly: {0}'.format(
            self.format_jobs(running_job))

    @botcmd(split_args_with=None)
    def build(self, mess, args):
        """Shortcut for jenkins_build"""
        return self.jenkins_build(mess, args)

    @botcmd
    def jenkins_unqueue(self, msg, args):
        """Cancel a queued job.
        Example !jenkins unqueue foo
        """
        self.connect_to_jenkins()

        try:
            queue = self.jenkins.get_queue_info()

            job = next((job for job in queue
                        if job['task']['name'].lower() == args.lower()), None)

            if job:
                self.jenkins.cancel_queue(job['id'])
                return 'Unqueued job {0}'.format(job['task']['name'])
            else:
                return 'Could not find job {0}, but found the following: {1}'.format(
                    args, ', '.join(job['task']['name'] for job in queue))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

    @botcmd(split_args_with=None)
    def jenkins_createjob(self, mess, args):
        """Create a Jenkins Job.
        Example: !jenkins createjob pipeline foo [email protected]:foo/bar.git
        """
        if len(args) < 2:  # No Job type or name
            return 'Oops, I need a type and a name for your new job.'

        if args[0] not in ('pipeline', 'multibranch'):
            return 'I\'m sorry, I can only create `pipeline` and \
                    `multibranch` jobs.'

        self.connect_to_jenkins()

        try:
            if args[0] == 'pipeline':
                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_PIPELINE.format(repository=args[2]))

            elif args[0] == 'multibranch':
                repository = args[2].rsplit('/', maxsplit=2)[-2:]

                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_MULTIBRANCH.format(
                        repo_owner=repository[0].split(':')[-1],
                        repo_name=repository[1].strip('.git')))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)
        return 'Your job has been created: {0}/job/{1}'.format(
            self.config['URL'], args[1])

    @botcmd(split_args_with=None)
    def jenkins_deletejob(self, mess, args):
        """Delete a Jenkins Job.
        Example: !jenkins deletejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablejob(self, mess, args):
        """Enable a Jenkins Job.
        Example: !jenkins enablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablejob(self, mess, args):
        """Disable a Jenkins Job.
        Example: !jenkins disablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been disabled.'

    @botcmd(split_args_with=None)
    def jenkins_createnode(self, mess, args):
        """Create a Jenkins Node with a JNLP Launcher with optionnal labels.
        Example: !jenkins createnode runner-foo-laptop /home/foo # without labels
        Example: !jenkins createnode runner-bar-laptop /home/bar linux docker # with labels
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need a name and a working dir for your new node.'

        self.connect_to_jenkins()

        try:
            self.jenkins.create_node(name=args[0],
                                     remoteFS=args[1],
                                     labels=' '.join(args[2:]),
                                     exclusive=True,
                                     launcher=LAUNCHER_JNLP)
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been created: {0}/computer/{1}'.format(
            self.config['URL'], args[0])

    @botcmd(split_args_with=None)
    def jenkins_deletenode(self, mess, args):
        """Delete a Jenkins Node.
        Example: !jenkins deletenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablenode(self, mess, args):
        """Enable a Jenkins Node.
        Example: !jenkins enablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablenode(self, mess, args):
        """Disable a Jenkins Node.
        Example: !jenkins disablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been disabled.'

    def search_job(self, search_term):
        self.log.debug('Querying Jenkins for job "{0}"'.format(search_term))
        return [
            job for job in self.jenkins.get_jobs(folder_depth=None)
            if search_term.lower() == job['fullname'].lower()
        ]

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return 'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join([
            '%s (%s)\n%s' % (job['name'], job['lastBuild']['url'],
                             job['healthReport'][0]['description'])
            for job in jobs_info
        ]).strip()

    @staticmethod
    def format_jobs(jobs):
        if len(jobs) == 0:
            return 'No jobs found.'

        max_length = max([len(job['fullname']) for job in jobs])
        return '\n'.join([
            '%s (%s)' % (job['fullname'].ljust(max_length), job['url'])
            for job in jobs
        ]).strip()

    @staticmethod
    def format_params(job):
        """Format job parameters."""
        if len(job) == 0:
            return 'This job is not parameterized.'
        PARAM_TEMPLATE = Template("""{% for p in params %}Type: {{p.type}}
Description: {{p.description}}
Default Value: {{p.defaultParameterValue.value}}
Parameter Name: {{p.name}}

{% endfor %}""")
        return PARAM_TEMPLATE.render({'params': job})

    @staticmethod
    def format_notification(body):
        body['fullname'] = body.get('fullname', body['name'])
        NOTIFICATION_TEMPLATE = Template("""Build #{{build.number}} \
{{build.status}} for Job {{fullname}} ({{build.full_url}})
{% if build.scm %}Based on {{build.scm.url}}/commit/{{build.scm.commit}} \
({{build.scm.branch}}){% endif %}""")
        return NOTIFICATION_TEMPLATE.render(body)

    @staticmethod
    def build_parameters(params):
        if len(params) > 0:
            return {
                param.split(':')[0]: param.split(':')[1]
                for param in params
            }
        return {'': ''}
class JenkinsNotifier(BotPlugin):
    """JenkinsBot is an Err plugin to manage Jenkins CI jobs from your chat platform like Slack."""

    status = {'blue':'SUCCESS', 'blue_anime':'IN PROGRESS','red': 'FAILED', 'red_anime': 'IN PROGRESS', 'disabled':   'DISABLED', 'aborted':'ABORTED', 'notbuilt': 'NOTBUILT', 'yellow': 'UNSTABLE'}
    failedjobsstring = " "


    def __init__(self, bot, name):
        self.jenkins = Jenkins(JENKINS_URL, JENKINS_USERNAME, JENKINS_TOKEN)
        super().__init__(bot, name) 


    @botcmd(split_args_with=None)
    def jn_build(self, msg, args):
        """Build the job specified by jobName. You can add params!"""

        # Params are passed like "key1=value1 key2=value2"
        params = {}
        #try:
        #    for arg in args[1:]:
        #        params[arg.split('=', 1)[0]] = arg.split('=', 1)[1]
        #except IndexError:
        #    return "I don'G like that params! Try with this format: key1=value1 key2=value2..."
        jobName = ''.join([args[0],' ',args[1]]) #TODO handle jobname with spaces in it, space is cosidered argument splitter  
        try:
            self.jenkins.build_job(jobName, params)
        except NotFoundException:
            return ' '.join(["Sorry, I can't find the job. Typo maybe?"," ARGS=",jobName])

        return ' '.join(["The job", args[0].strip(), "has been sent to the queue to be built."])


    @botcmd
    def jn_cancel(self, msg, args):
        """Cancel a job in the queue by jobId."""

        try:
            self.jenkins.cancel_queue(args.strip())
        except NotFoundException:
            return "Sorry, I can't find the job. Maybe the ID does not exist."

        return "Job canceled from the queue."


    @botcmd
    def jn_list(self, msg, args):
        """List Jenkins jobs. You can filter with strings."""

        self.send(msg.to, "I'm getting the jobs list from Jenkins...")

        search_term = args.strip().lower()
        jobs = [job for job in self.jenkins.get_jobs()
                if search_term.lower() in job['name'].lower()]

        return self.format_jobs(jobs)


    @botcmd
    def jn_status(self, msg, args):
        """List Jenkins jobs with their current status."""

        self.send(msg.to, "I'm getting the jobs with status Jenkins...")

        search_term = args.strip().lower()
        jobs = [job for job in self.jenkins.get_jobs()
                if search_term.lower() in job['fullname'].lower()]

        return self.format_job_status(jobs)




    @botcmd
    def jn_describe(self, msg, args):
        """Describe the job specified by jobName."""

        try:
            job = self.jenkins.get_job_info(args.strip())
        except NotFoundException:
            return "Sorry, I can't find the job. Typo maybe?"

        return ''.join([
            'Name: ', job['name'], '\n',
            'URL: ', job['url'], '\n',
            'Description: ', 'None' if job['description'] is None else job['description'], '\n',
            'Next Build Number: ',
            str('None' if job['nextBuildNumber'] is None else job['nextBuildNumber']), '\n',
            'Last Successful Build Number: ',
            str('None' if job['lastBuild'] is None else job['lastBuild']['number']), '\n',
            'Last Successful Build URL: ',
            'None' if job['lastBuild'] is None else job['lastBuild']['url'], '\n'
        ])


    @botcmd
    def jn_running(self, msg, args):
        """List running jobs."""

        self.send(msg.to, "I will ask for the current running builds list!")

        jobs = self.jenkins.get_running_builds()

        return self.format_running_jobs(jobs)


    @botcmd(split_args_with=None)
    def jn_stop(self, msg, args):
        """Stop the building job specified by jobName and jobNumber."""

        try:
            int(args[1].strip())
        except ValueError:
            return "You have to specify the jobNumber: \"!jenkins stop <jobName> <jobNumber>"

        try:
            self.jenkins.stop_build(args[0].strip(), int(args[1].strip()))
        except NotFoundException:
            return "Sorry, I can't find the job. Typo maybe?"

        return ' '.join(["The job", args[0].strip(), "has been stopped."])


    @botcmd
    def jn_queue(self, msg, args):
        """List jobs in queue."""

        self.send(msg.to, "Getting the job queue...")

        jobs = self.jenkins.get_queue_info()

        return self.format_queue_jobs(jobs)


    @botcmd
    def jn_msgtimer(self, msg, args):
        """Sends messages at fix intervals."""
        yield "Starting timer"
        self.start_poller(5, self.my_callback)
        self.send(msg.to,
        "Boo! Bet you weren't expecting me, were you?", 
        )


    def my_callback(self):
        self.log.info('I am called every 5sec')
        self.send(self.build_identifier("#errbottestchannel"), "I am called every 5sec", )

    @botcmd 
    def jn_failed(self, msg, args):

        """List Jenkins jobs with failed status."""
        self.send(msg.to, "I'm getting the failed jobs ...")
        failedJobs = []
        search_term = args.strip().lower()
        jobs = [job for job in self.jenkins.get_jobs()
                if search_term.lower() in job['fullname'].lower()]
        for job in jobs:
            if self.status[job['color']] == 'FAILED':
               failedJobs.append(job)
        return self.format_job_status(failedJobs)



# SUPPORT FUNCTIONS START HERE

    def format_jobs(self, jobs):
        """Format jobs list"""

        if len(jobs) == 0:
            return "I haven't found any job."

        max_length = max([len(job['name']) for job in jobs])
        return '\n'.join(['%s (%s)' % (job['name'].ljust(max_length),
                                       job['url']) for job in jobs]).strip()


    def format_queue_jobs(self, jobs):
        """Format queue jobs list"""

        if len(jobs) == 0:
            return "It seems that there is not jobs in queue."

        return '\n'.join(['%s - %s (%s)' % (str(job['id']),
                                            job['task']['name'],
                                            job['task']['url']) for job in jobs]).strip()


    def format_running_jobs(self, jobs):
        """Format running jobs list"""

        if len(jobs) == 0:
            return "There is no running jobs!"

        return '\n'.join(['%s - %s (%s) - %s' % (str(job['number']),
                                                 job['name'],
                                                 job['url'],
                                                 job['executor']) for job in jobs]).strip()

    @botcmd
    def jn_queue(self, msg, args):
        """List jobs in queue."""

        self.send(msg.to, "Getting the job queue...")

        jobs = self.jenkins.get_queue_info()

        return self.format_queue_jobs(jobs)


    def format_jobs(self, jobs):
        """Format jobs list"""

        if len(jobs) == 0:
            return "I haven't found any job."

        max_length = max([len(job['name']) for job in jobs])
        return '\n'.join(['%s (%s)' % (job['name'].ljust(max_length),
                                       job['url']) for job in jobs]).strip()


    def format_queue_jobs(self, jobs):
        """Format queue jobs list"""

        if len(jobs) == 0:
            return "It seems that there is not jobs in queue."

        return '\n'.join(['%s - %s (%s)' % (str(job['id']),
                                            job['task']['name'],
                                            job['task']['url']) for job in jobs]).strip()


    def format_running_jobs(self, jobs):
        """Format running jobs list"""

        if len(jobs) == 0:
            return "There is no running jobs!"

        return '\n'.join(['%s - %s (%s) - %s' % (str(job['number']),
                                                 job['name'],
                                                 job['url'],
                                                 job['executor']) for job in jobs]).strip()

    def format_job_status(self, jobs):
        """Format job status"""

        if len(jobs) == 0:
            return "there are no jobs to return"
        return '\n'.join(['%s (%s)' % (job['fullname'], self.status[job['color']]) for job in jobs]).strip()
Beispiel #14
0
class JenkinsHelper:
    def __init__(self, url, username, password, key, configuration):
        self.configuration = configuration
        self.configuration_prefix = configuration.jenkins_configuration_prefix()
        self.grouped_components = configuration.jenkins_grouped_components()
        self.pullrequest_job = configuration.pullrequest_job()

        self.jenkins_configurations = Jenkins(url, username, password)
        self.build_components_jobs_matrix()
        self.sort_components()

        self.jenkins_builds = jenkinsapi.jenkins.Jenkins(url, username, password)

# Getters
    def get_jobs(self):
        return self.jobs

    def get_components(self):
        return self.components

    def get_pull_request_builds(self):
        job = self.jenkins_builds.get_job(self.pullrequest_job)

        self.pullrequest_builds = {}
        for build_id in job.get_build_ids():
            build = job[build_id]
            self.pullrequest_builds[build.buildno] = {}
            self.pullrequest_builds[build.buildno]['status'] = build.get_status()
            self.pullrequest_builds[build.buildno]['url'] = build.baseurl
            self.pullrequest_builds[build.buildno]['name'] = build.name

            revision = build.get_revision_branch()[0]
            self.pullrequest_builds[build.buildno]['revision'] = revision['SHA1']
            self.pullrequest_builds[build.buildno]['revision_name'] = revision['name']

        return self.pullrequest_builds

# Helper methods
    def initial_jobs_info(self):
        wanted_jobs, wanted_ids = self.configuration.jenkins_jobs()
        jobs = self.wanted_jobs(wanted_jobs)
        return self.add_human_name_to_job(jobs, wanted_ids)

    def sort_components(self):
        self.components = OrderedDict(sorted(self.components.items(), key=lambda x: self.sorting_modification(x)))

    def build_components_jobs_matrix(self):
        self.jobs = self.initial_jobs_info()

        self.components = {}
        for job in self.jobs:
            groups = {}
            job_raw_components = self.jenkins_configurations.get_job_info(job['name'])["activeConfigurations"]

            job['components'] = {}
            for raw_component in job_raw_components:
                self.process_component(raw_component, job, groups)

            for name, group in groups.iteritems():
                job['components'][name] = group
                self.add_group_to_components(name, group)

    def add_group_to_components(self, name, group):
        self.components[name] = {}
        self.components[name]['name'] = group['name']
        self.components[name]['global_class'] = 'group'
        self.components[name]['type'] = 'group';

    def process_component(self, raw_component, job, groups):
        name = raw_component['name'].replace(self.configuration_prefix, '')

        if name not in self.components:
            self.components[name] = {}
            self.components[name]['name'] = name

        job['components'][name] = {};
        job['components'][name]['name'] = name;
        job['components'][name]['color'] = raw_component['color']
        job['components'][name]['href'] = raw_component['url']

        # Manage grouped components
        grouped_component = self.has_to_be_grouped(name, self.grouped_components)
        if grouped_component:
            self.components[name]['global_class'] = grouped_component + ' hide grouped'

            # Create component group entry
            group_name = grouped_component + '_grouped'
            if not group_name in groups:
                groups[group_name] = {'name': grouped_component, 'color': ''}

            groups[group_name]['color'] = self.logical_color_conjunction(
                                                        groups[group_name]['color'],
                                                        raw_component['color'])

# Second level helper methods
    def wanted_jobs(self, wanted_jobs):
        jobs = self.jenkins_configurations.get_jobs()

        return [ job for job  in jobs if job['name'] in wanted_jobs ]

    def add_human_name_to_job(self, jobs, wanted_jobs_ids):
        for i in range(len(jobs)):
            jobs[i]['short_name'] = wanted_jobs_ids[i]

        return jobs


    def has_to_be_grouped(self, name, grouped_configuration):
        for keyword in grouped_configuration:
            if name.find(keyword) == 0:
                return keyword

        return False


    def logical_color_conjunction(self, color1, color2):
        if (color1 == 'red' or color2 == 'red'):
            return 'red'
        if (color1 == 'yellow' or color2 == 'yellow'):
            return 'yellow'
        if (color1 == 'blue' or color2 == 'blue'):
            return 'blue'

        return 'white'

    def sorting_modification(self, value):
        if ('type' in value[1]) and (value[1]['type'] == 'group'):
            return value[1]['name']

        return value[0] + "_"
Beispiel #15
0
class JenkinsBot(BotPlugin):
    """JenkinsBot is an Err plugin to manage Jenkins CI jobs from your chat platform like Slack."""
    def __init__(self, bot):
        self.jenkins = Jenkins(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD)
        super().__init__(bot)

    @botcmd(split_args_with=None)
    def jenkins_build(self, msg, args):
        """Build the job specified by jobName. You can add params!"""

        # Params are passed like "key1=value1 key2=value2"
        params = {}
        try:
            for arg in args[1:]:
                params[arg.split('=', 1)[0]] = arg.split('=', 1)[1]
        except IndexError:
            return "I don't like that params! Try with this format: key1=value1 key2=value2..."

        try:
            self.jenkins.build_job(args[0].strip(), params)
        except NotFoundException:
            return "Sorry, I can't find the job. Typo maybe?"

        return ' '.join([
            "The job", args[0].strip(),
            "has been sent to the queue to be built."
        ])

    @botcmd
    def jenkins_cancel(self, msg, args):
        """Cancel a job in the queue by jobId."""

        try:
            self.jenkins.cancel_queue(args.strip())
        except NotFoundException:
            return "Sorry, I can't find the job. Maybe the ID does not exist."

        return "Job canceled from the queue."

    @botcmd
    def jenkins_list(self, msg, args):
        """List Jenkins jobs. You can filter with strings."""

        self.send(msg.to, "I'm getting the jobs list from Jenkins...")

        search_term = args.strip().lower()
        jobs = [
            job for job in self.jenkins.get_jobs()
            if search_term.lower() in job['name'].lower()
        ]

        return self.format_jobs(jobs)

    @botcmd
    def jenkins_describe(self, msg, args):
        """Describe the job specified by jobName."""

        try:
            job = self.jenkins.get_job_info(args.strip())
        except NotFoundException:
            return "Sorry, I can't find the job. Typo maybe?"

        return ''.join([
            'Name: ', job['name'], '\n', 'URL: ', job['url'], '\n',
            'Description: ',
            'None' if job['description'] is None else job['description'], '\n',
            'Next Build Number: ',
            str('None'
                if job['nextBuildNumber'] is None else job['nextBuildNumber']),
            '\n', 'Last Successful Build Number: ',
            str('None' if job['lastBuild'] is None else job['lastBuild']
                ['number']), '\n', 'Last Successful Build URL: ',
            'None' if job['lastBuild'] is None else job['lastBuild']['url'],
            '\n'
        ])

    @botcmd
    def jenkins_running(self, msg, args):
        """List running jobs."""

        self.send(msg.to, "I will ask for the current running builds list!")

        jobs = self.jenkins.get_running_builds()

        return self.format_running_jobs(jobs)

    @botcmd(split_args_with=None)
    def jenkins_stop(self, msg, args):
        """Stop the building job specified by jobName and jobNumber."""

        try:
            int(args[1].strip())
        except ValueError:
            return "You have to specify the jobNumber: \"!jenkins stop <jobName> <jobNumber>"

        try:
            self.jenkins.stop_build(args[0].strip(), int(args[1].strip()))
        except NotFoundException:
            return "Sorry, I can't find the job. Typo maybe?"

        return ' '.join(["The job", args[0].strip(), "has been stopped."])

    @botcmd
    def jenkins_queue(self, msg, args):
        """List jobs in queue."""

        self.send(msg.to, "Getting the job queue...")

        jobs = self.jenkins.get_queue_info()

        return self.format_queue_jobs(jobs)

    def format_jobs(self, jobs):
        """Format jobs list"""

        if len(jobs) == 0:
            return "I haven't found any job."

        max_length = max([len(job['name']) for job in jobs])
        return '\n'.join([
            '%s (%s)' % (job['name'].ljust(max_length), job['url'])
            for job in jobs
        ]).strip()

    def format_queue_jobs(self, jobs):
        """Format queue jobs list"""

        if len(jobs) == 0:
            return "It seems that there is not jobs in queue."

        return '\n'.join([
            '%s - %s (%s)' %
            (str(job['id']), job['task']['name'], job['task']['url'])
            for job in jobs
        ]).strip()

    def format_running_jobs(self, jobs):
        """Format running jobs list"""

        if len(jobs) == 0:
            return "There is no running jobs!"

        return '\n'.join([
            '%s - %s (%s) - %s' %
            (str(job['number']), job['name'], job['url'], job['executor'])
            for job in jobs
        ]).strip()
def main():
	print "This is automated report generated by [email protected] on " + datetime.now().strftime("%Y-%m-%d %H:%M")

	address = 'http://developers.compbio.cs.cmu.edu:8080'
	j = Jenkins(address)
	jobs = j.get_jobs()

	print '------------------------'
	print 'CellOrganizer for Matlab'
	print '------------------------'

	success_table = []
	failure_table = []
	other_table = []
	successes = 0
	failures = 0
	for job in jobs:
		if 'cellorganizer-demo3D' in job['name'] or 'cellorganizer-demo2D' in job['name']:
			status = get_status(job['color'])
			if status == 'SUCCESS':
				successes += 1
				success_table.append([job['name'], status])
			elif status == 'FAILURE':
				failures += 1
				failure_table.append([job['name'], status])
			else:
				other_table.append([job['name'], status])

	print "\nSuccessful Jobs Table"
	print tabulate(success_table, headers=["Name","Status"], tablefmt='grid')

	print "\nFailed Jobs Table"
	print tabulate(failure_table, headers=["Name","Status"], tablefmt='grid')

	if '++\n++' != tabulate(other_table, headers=["Name","Status"], tablefmt='grid'):
		print "\nOther Jobs"
		print tabulate(other_table, headers=["Name","Status"], tablefmt='grid')

	print "\nNumber of Total Successes: " + str(successes)
	print "Number of Total Failures " + str(failures)

	print '\n\n------------------------'
	print 'CellOrganizer for Python'
	print '------------------------'

	success_table = []
	failure_table = []
	other_table = []
	successes = 0
	failures = 0
	for job in jobs:
		if 'cellorganizer' in job['name'] and 'python' in job['name']:
			status = get_status(job['color'])
			if status == 'SUCCESS':
				successes += 1
				success_table.append([job['name'], status])
			elif status == 'FAILURE':
				failures += 1
				failure_table.append([job['name'], status])
			else:
				other_table.append([job['name'], status])

	print "\nSuccessful Jobs Table"
	print tabulate(success_table, headers=["Name","Status"], tablefmt='grid')

	print "\nFailed Jobs Table"
	print tabulate(failure_table, headers=["Name","Status"], tablefmt='grid')

	if '++\n++' != tabulate(other_table, headers=["Name","Status"], tablefmt='grid'):
		print "\nOther Jobs"
		print tabulate(other_table, headers=["Name","Status"], tablefmt='grid')

	print "\nNumber of Total Successes: " + str(successes)
	print "Number of Total Failures " + str(failures)
Beispiel #17
0
class JenkinsTools(object):
    """
    This is to expose the functional capability of jenkins for the various operations that it can perform programatically without having access to console.
    """

    _jenkins_url = None
    _login_id = None
    _password = None

    def __init__(self, jenkins_url, login_id, password):
        """
        Initialize the jenkins connection object
        :param jenkins_url:
        :param login_id:
        :param password:
        """
        self._jenkins_url = jenkins_url
        self._login_id = login_id
        self._password = password
        self.server_obj = Jenkins(jenkins_url, username=self._login_id, password=self._password)

    def get_jenkins_version(self):
        """
        To get the Jenkins version
        :return:
        """
        return self.server_obj.get_version()

    def get_job_details(self):
        """
        Get the jenkins job details.
        :return:
        """
        for job in self.server_obj.get_jobs():
            job_instance = self.server_obj.get_job(job[0])
            print 'Job Name:%s' % job_instance.name
            print 'Job Description:%s' %(job_instance.get_description())
            print 'Is Job running:%s' %(job_instance.is_running())
            print 'Is Job enabled:%s' %(job_instance.is_enabled())

    def get_job_count(self):
        """
        To get the count of jobs in Jenkins
        :return:
        """
        return self.server_obj.jobs_count()

    def disable_jenkins_job(self, job_name=None):
        """
        To  disable the jobs from jenkins.
        :return:
        """
        if self.server_obj.has_job(job_name):
            job_instance = self.server_obj.get_job(job_name)
            job_instance.disable()
            print 'Name:%s,Is Job Enabled ?:%s' % (job_name, job_instance.is_enabled())

    def get_jenkins_plugin_details(self):
        """
        To get the details of existing plugins in jenkins.
        :return:
        """
        for plugin in self.server_obj.get_plugins().values():
            print "Short Name:%s" % plugin.shortName
            print "Long Name:%s" % plugin.longName
            print "Version:%s" % plugin.version
            print "URL:%s" % plugin.url
            print "Active:%s" % plugin.active
            print "Enabled:%s" % plugin.enabled

    def get_plugin_details(self, plugin_name):
        """
        TO get the new plugin details
        :param plugin_name:
        :return:
        """
        plugins_metadata = self.server_obj.get_plugin_info(plugin_name)
        pprint(plugins_metadata)

    def getSCMInfroFromLatestGoodBuild(url, jobName, username=None, password=None):
        """
        To get the latest SCM from the latest good builds.
        :param url:
        :param jobName:
        :param username:
        :param password:
        :return:
        """
        J = Jenkins(url, username, password)
        job = J[jobName]
        lgb = job.get_last_good_build()
        return lgb.get_revision()
Beispiel #18
0
class JC:
    def __init__(self):
        self.JCDirectoryLoc = ''
        self.JCBuiltFileLoc = ''
        self.JCServerConfFileLoc = ''
        self.JenkinsServerAddress = 'none'
        self.JenkinsServerPort = 'none'
        self.ServerHandler = None
        self.IpRegex = '''^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 
            25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 
            25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 
            25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)'''

        self.JCSelectedJobCommands = {
            '(enable)': ' - Enable the specified job on Jenkins Server',
            '(disable)': ' - Disable the specified job on Jenkins Server',
            '(build)': ' - Build the specified job on Jenkins Server',
            '(stat [*])': ' - Displays status and general information about the specified job',
            '(?)': ' - Displays list of available commands',
            '(??)': ' - Displays list of available commands verbosely',
            '(quit/exit)': ' - Quit Job configuration mode'

        }

        self.JigGlobalCommands = {
            '(show local jobs [*])': ' - Displays all jobs saved and waiting in your local machine to be created on server',
            '(show server jobs)': ' - Displays all jobs currently on your jenkins server',
            '(show build queue)': ' - Displays all jobs in build queue',
            '(delete local job)': ' - Deletes jobs on your local machine',
            '(delete server job)': ' - Deletes jobs on your jenkins server',
            '(reconfig server job)': ' - Reconfigures an existing job',
            '(select server job)': ' - Selects job and enter job configuration mode',
            '(connect)': ' - Connects to jenkins server',
            '(disconnect)': ' - Disconnects from jenkins server',
            '(create server job)': ' - Creates a new job on server ',
            '(?)': ' - Displays list of available commands',
            '(??)': ' - Displays list of available commands verbosely',
            '(exit / quit)': ' - Quit JC program'

        }

    def initialize(self):

        fh=open("C:\\Users\{0}\JC\controls".format(getuser()))
        for line in fh:
            if line.startswith('server.conf'):
                self.JCServerConfFileLoc=(line.split("=")[1]).strip()
            elif line.startswith('jobdir'):
                self.JCDirectoryLoc=(line.split("=")[1]).strip()
            elif line.startswith('built'):
                self.JCBuiltFileLoc=(line.split("=")[1]).strip()
            elif line.startswith('address'):
                self.JenkinsServerAddress=(line.split("=")[1]).strip()
            elif line.startswith('port'):
                self.JenkinsServerPort=(line.split("=")[1]).strip()
        fh.close()


    def display_introduction(self):
        '''
        Display an introduction message for the program containing the version and status of
        development
        '''

        print("     Welcome to JC 1.4")
        print("JC is a project which creates an interface to manage your Jenkins Server for your projects")
        print("This project is still under development ")

    def display_list_of_global_mode_commands(self, verbos=False, search_key=None):
        '''
        Display list of available commands in global mode

        :param verbos:  display description of command(s) if true
        :param search_key: display all commands starts with the 'key' param . default is None meaning all available commands

        '''

        print("---------------Commands---------------")
        if search_key is None:
            for command, description in self.JigGlobalCommands.items():
                print(command, description if verbos else '')
        else:
            for command, description in self.JigGlobalCommands.items():

                if command.startswith('({0}'.format(search_key)):
                    print(command, description if verbos else '')
        print("---------------------------------------")

    def display_list_of_selected_job_mode_commands(self, verbos=False, search_key=None):

        '''
        Display list of available commands in selected job mode

        :param verbos: display description of command(s) if true
        :param search_key: display all commands starts with the 'key' param . default is None meaning all available commands

        '''

        print("---------------Commands---------------")
        if search_key is None:
            for command, description in self.JCSelectedJobCommands.items():
                print(command, description if verbos else '')
        else:
            for command, description in self.JCSelectedJobCommands.items():
                if command.startswith('({0}'.format(search_key)):
                    print(command, description if verbos else '')
        print("---------------------------------------")

    def show_local_jobs(self, Detail=False):
        '''
        Display list of local jobs
        :param Detail: If True , Displays more detail about local jobs
        :return:
        '''

        # TODO display format
        if len(listdir(self.JCDirectoryLoc)) == 0:
            print("No local job")
        else:
            if Detail:
                print("Status".ljust(8), "CRL".ljust(23), "CRS".ljust(23), "RCFG".ljust(23), "Name")
                print("-----".ljust(8), "--------".ljust(23), "--------".ljust(23), "--------".ljust(23), "-----")

            else:
                print("Status".ljust(8),"Name".ljust(20))
                print("-----".ljust(8), "-----".ljust(33))

            fhandle = open(self.JCBuiltFileLoc)
            for line in fhandle:
                line = line.strip()
                if line.startswith("#"):
                    pass
                else:
                    if Detail:
                        Status=(line.split("@")[0]).ljust(8)
                        CRL = ((line.split("@")[1]).split(".")[0]).ljust(23)
                        CRS = ((line.split("@")[2]).split(".")[0] if line.split("@")[2]!='None' else 'None').ljust(23)
                        RCFG = ((line.split("@")[3]).split(".")[0] if line.split("@")[3]!='None' else 'None').ljust(23)
                        Name= (line.split("@")[4])
                        print(Status,CRL,CRS,RCFG,Name)
                    else:
                        Status = (line.split("@")[0]).ljust(8)
                        Name= (line.split("@")[4])
                        print(Status,Name)

            fhandle.close()



    def connect_to_jenkins_server(self):

        # Because if there is a problem in reading server.conf file
        # both IP address and Port number becomes none
        # so we just check server address to be none or not


        fh=open("C:\\Users\{0}\JC\controls".format(getuser()))
        for line in fh:
            if line.startswith('address'):
                self.JenkinsServerAddress=(line.split("=")[1]).strip()
            elif line.startswith('port'):
                self.JenkinsServerPort=(line.split("=")[1]).strip()
        fh.close()

        if self.JenkinsServerAddress !='none':
            print("Connecting {0}:{1}".format(self.JenkinsServerAddress, self.JenkinsServerPort))
            UserName = input("Username : "******"Password : "******"Connected successfully as {2}".format(self.JenkinsServerAddress, self.JenkinsServerPort, UserName))
            except:
                self.ServerHandler = None
                print("Connection to server Failed")

        else:
            print("-Server configuration parameters are not defined properly")
            print("-Check server.conf for parameters and then use jcr.exe to set them")


    def is_connected(self):
        '''
        Check whether we are connected to server or not
        '''
        return True if self.ServerHandler else False

    def disconnect_from_jenkins_server(self, place=None):
        '''
        Disconnect from the server
        :param place: Defines the place we are disconnecting . Displayed message can be different based on this parameter
        '''
        # TODO Close the TCP PORT

        if self.ServerHandler == None:
            # Disconnect and Stay in the program
            if place is None:
                print("You are already disconnected")
            return
        self.ServerHandler = None
        # Disconnect while exiting the program
        print("You are disconnected successfully")

    def create_server_job(self, JobName):
        '''
        Create a server job based on a config.xml file existing on the local machine
        :param JobName: job's name to be created
        '''

        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        if not path.exists('{0}{1}{2}'.format(self.JCDirectoryLoc, JobName, '.config.xml')):
            print("-Job '{0}' config.xml file does not exist on your local machine".format(JobName))
            print("First create a config.xml file for job {0} by jigjr command".format(JobName))
        else:
            ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
            if JobName in ListServerJobs:
                print("-Job '{0}' already exists on the server".format(JobName))
                AskingResult = self.asking_user_decision("Do you want to recreate job {0}?[y/n] : ".format(JobName))

                if AskingResult:
                    self.ServerHandler.delete_job(JobName)
                    print("-Deleting job '{0}' from server ..".format(JobName))

                    fhandle = open(self.JCDirectoryLoc + JobName + ".config.xml")
                    SelectedJobXml = fhandle.read()
                    fhandle.close()
                    self.ServerHandler.create_job(JobName, SelectedJobXml)
                    print("-Job '{0}' recreated successfully".format(JobName))

                    # Recreate a job is similar to reconfigure that job
                    update_built_file(self.JCBuiltFileLoc, 'update-reconfigure-date', JobName,
                                      reconfig_date=datetime.now())

            else:
                AskingResult = self.asking_user_decision("Sure creating job {0}?[y/n] : ".format(JobName))
                if AskingResult:
                    fhandle = open(self.JCDirectoryLoc + JobName + ".config.xml")
                    SelectedJobXml = fhandle.read()
                    fhandle.close()
                    self.ServerHandler.create_job(JobName, SelectedJobXml)
                    print("-Job '{0}' created successfully".format(JobName))
                    update_built_file(self.JCBuiltFileLoc, 'update-server-create-date', JobName,
                                      server_creation_date=datetime.now())

    def reconfigure_server_job(self, JobName, LocalConfigJobName=None):
        '''
        Reconfigure a server job
        :param JobName: Server job to be configured
        :param LocalConfigJobName:  If None , JobName.config.xml file is searched in local machine , else, LocalConfigJobName.config.xml is searched
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
        if JobName not in ListServerJobs:
            print("-Job '{0}' does not exist on the server".format(JobName))

        else:
            ListLocalJobs = [job.split(".")[0] for job in listdir(self.JCDirectoryLoc)]

            # If the LocalConfigJobName is not specified use the JobName as defualt
            LocalConfigJobName = JobName if LocalConfigJobName is None else LocalConfigJobName

            if LocalConfigJobName not in ListLocalJobs:
                print("-Job {0} config.xml file does not exist in your local machine".format(LocalConfigJobName))

            else:
                print("{0}.config.xml found".format(LocalConfigJobName))
                AskingResult = self.asking_user_decision("Sure reconfiguring job {0}?[y/n] : ".format(JobName))
                if AskingResult:
                    fhandle = open(self.JCDirectoryLoc + LocalConfigJobName + ".config.xml")
                    SelectedJobXml = fhandle.read()
                    fhandle.close()
                    self.ServerHandler.reconfig_job(LocalConfigJobName, SelectedJobXml)
                    print("-Job '{0}' reconfigured successfully".format(LocalConfigJobName))
                    update_built_file(self.JCBuiltFileLoc, 'update-reconfigure-date', LocalConfigJobName,
                                      reconfig_date=datetime.now())

    def show_build_queue(self):
        '''
        Display list of jobs which are currently under building process
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            BuildQueue = self.ServerHandler.get_queue_info()
            if len(BuildQueue) == 0:
                print("No job in build queue")
                return
            else:
                BuildQueueCounter = 1
                for job in BuildQueue:
                    jobInfo = self.ServerHandler.get_job_info(job['task']['name'])
                    print("{0}: {1}\tBuilding No: {2}".format(BuildQueueCounter, job["task"]["name"],
                                                              jobInfo['nextBuildNumber']))
                    BuildQueueCounter += 1

    def show_server_jobs(self):
        '''
        Display list of jobs currently configured on the server
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            if len(self.ServerHandler.get_jobs()) == 0:
                print("No job currently on the server")
            else:
                ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
                # This list is to reduce the latency of display of all jobs
                # First collect information of all jobs then display
                ReadyList = []
                for job in ListServerJobs:
                    JobInfo = self.ServerHandler.get_job_info(job)
                    JobStatus = 'Disabled' if JobInfo['disabled'] else 'Enabled'
                    JobTotalBuilds = "0" if JobInfo['lastBuild'] is None else JobInfo['lastBuild']['number']
                    JobLastBuild = "None" if JobInfo['lastBuild'] is None else datetime.fromtimestamp(
                        self.ServerHandler.get_build_info(job, JobInfo['lastBuild']['number'])['timestamp'] / 1000)
                    ReadyList.append([JobStatus, JobTotalBuilds, JobLastBuild, job])

                print("Status".ljust(8), "Build".ljust(7), "Timestamp".ljust(22), "Name".ljust(20))
                print("-----".ljust(8), "-----".ljust(7), "------".ljust(22), "----".ljust(20))

                for j in ReadyList:
                    print(j[0].ljust(9), str(j[1]).ljust(6),('None' if str(j[2]) == 'None' else str(j[2]).split(".")[0]).ljust(22), j[3].ljust(20))



    def delete_local_job(self, JobName):
        '''
        Delete local jobs
        '''

        LocalJobs = [job.split(".")[0] for job in listdir(self.JCDirectoryLoc)]

        if JobName not in LocalJobs:
            print("-Job '{0}' does not exist in your local machine".format(JobName))
            return
        else:
            AskingResult = self.asking_user_decision("Sure deleting job '{0}'?[y/n] : ".format(JobName))
            if AskingResult:
                remove(self.JCDirectoryLoc + JobName + ".config.xml")
                print("-Job '{0}' removed successfully from your local machine".format(JobName))

                update_built_file(self.JCBuiltFileLoc, 'delete', JobName)

    def delete_server_job(self, JobName):
        '''
        Delete Specified server job
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
            if JobName not in ListServerJobs:
                print("-Job '{0}' does not exist in Jenkins Server".format(JobName))
                return
            else:
                AskingResult = self.asking_user_decision("Sure deleting job '{0}'?[y/n]: ".format(JobName))
                if AskingResult:
                    self.ServerHandler.delete_job(JobName)
                    print("-Job '{0}' removed successfully from server".format(JobName))
                    update_built_file(self.JCBuiltFileLoc, 'update-deploy-status-ND', JobName)

    def disable_server_job(self, JobName):
        '''
        Disable specified server job
        '''

        JobState = self.ServerHandler.get_job_info(JobName)['disabled']
        if JobState:
            print("-Job '{0}' is already disabled".format(JobName))
            return
        self.ServerHandler.disable_job(JobName)
        print("-Job '{0}' successfully disabled".format(JobName))

    def enable_server_job(self, JobName):
        '''
        Enable specified server job
        '''
        JobState = self.ServerHandler.get_job_info(JobName)['disabled']
        if not JobState:
            print("-Job '{0}' is already enabled".format(JobName))
            return
        self.ServerHandler.enable_job(JobName)
        print("-Job '{0}' successfully enabled".format(JobName))

    def build_server_job(self, JobName):
        '''
        Build specified server job
        '''
        JobState = self.ServerHandler.get_job_info(JobName)['disabled']
        if JobState:
            print("-Job '{0}' is disabled and cannot built".format(JobName))
        else:
            self.ServerHandler.build_job(JobName)
            print("-Job '{0}' successfully built".format(JobName))

    def stat_server_job(self, JobName, Detail=False):
        '''
        Display status of the selected job
        :param Detail: If * specified , more detail about job is displayed
        '''

        # Because building a job can take long time we do not display the status
        # until the building process gets done
        BuildQueue = self.ServerHandler.get_queue_info()

        for job in BuildQueue:
            if JobName == job["task"]["name"]:
                print("-Job '{0}' is under building process".format(JobName))
                return

        JobInfo = self.ServerHandler.get_job_info(JobName)
        JobName_Sta = "Name: {0}".format(JobName)
        JobStatus_Sta = "Status: {0}".format('Disabled' if JobInfo['disabled'] else 'Enabled')
        JobTotalBuilds_Sta = "TotalBuilds: {0}".format(
            "0" if JobInfo['lastBuild'] is None else JobInfo['lastBuild']['number'])
        JobLastBuild_Sta = "LastBuild: {0}".format("None" if JobInfo['lastBuild'] is None else datetime.fromtimestamp(
            self.ServerHandler.get_build_info(JobName, JobInfo['lastBuild']['number'])['timestamp'] / 1000))
        JobFirstBuild_Sta = "FirstBuild: {0}".format("None" if JobInfo['lastBuild'] is None else datetime.fromtimestamp(
            self.ServerHandler.get_build_info(JobName, JobInfo['lastBuild']['number'])['timestamp'] / 1000))

        JobLastCompletedBuild_Sta = "LastCompletedBuild: {0}".format(
            "None" if JobInfo['lastCompletedBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastCompletedBuild']['number'])[
                    'timestamp'] / 1000)).split(".")[0])
        JobLastFailedBuild_Sta = "LastFailedBuild: {0}".format(
            "None" if JobInfo['lastFailedBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastFailedBuild']['number'])['timestamp'] / 1000)).split(".")[0])
        JobLastStableBuild_Sta = "LastStableBuild: {0}".format(
            "None" if JobInfo['lastStableBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastStableBuild']['number'])['timestamp'] / 1000)).split(".")[0])
        JobLastSuccessfulBuild_Sta = "LastSuccessfulBuild: {0}".format(
            "None" if JobInfo['lastSuccessfulBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastSuccessfulBuild']['number'])[
                    'timestamp'] / 1000)).split(".")[0])
        JobLastUnstableBuild_Sta = "LastUnstableBuild: {0}".format(
            "None" if JobInfo['lastUnstableBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastUnstableBuild']['number'])['timestamp'] / 1000)).split(".")[0])
        JobLastUnsuccessfulBuild_Sta = "LastUnsuccessfulBuild: {0}".format(
            "None" if JobInfo['lastUnsuccessfulBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastUnsuccessfulBuild']['number'])[
                    'timestamp'] / 1000)).split(".")[0])

        print(JobName_Sta)
        print(JobStatus_Sta)
        print(JobTotalBuilds_Sta)
        print(JobLastBuild_Sta)
        print(JobLastStableBuild_Sta)
        print(JobLastCompletedBuild_Sta)

        if Detail:
            print(JobFirstBuild_Sta)
            print(JobLastFailedBuild_Sta)
            print(JobLastSuccessfulBuild_Sta)
            print(JobLastUnstableBuild_Sta)
            print(JobLastUnsuccessfulBuild_Sta)

    def select_server_job(self, JobName):
        '''
        Select a server job and enter selected job mode
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:

            ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
            if JobName not in ListServerJobs:
                print("-Job '{0}'  not exist in Jenkins Server".format(JobName))
                return
            else:
                SelectedJobSession = PromptSession(
                    lexer=PygmentsLexer(SqlLexer), completer=selected_job_command_completer)
                while True:

                    try:
                        UserCommand = SelectedJobSession.prompt("(" + JobName + ')## ')
                        UserCommand = (sub(' +', ' ', UserCommand)).strip()

                        if UserCommand.startswith("??"):
                            keyValue = (UserCommand.split("??")[1].strip())
                            if keyValue == '':
                                jc.display_list_of_selected_job_mode_commands(verbos=True)
                            else:
                                jc.display_list_of_selected_job_mode_commands(search_key=keyValue, verbos=True)

                        elif UserCommand.startswith("?"):
                            keyValue = (UserCommand.split("?")[1].strip())

                            if keyValue == '':
                                jc.display_list_of_selected_job_mode_commands()
                            else:
                                jc.display_list_of_selected_job_mode_commands(search_key=keyValue)


                        elif UserCommand == "quit" or UserCommand == "exit":
                            return

                        elif UserCommand == "enable":
                            self.enable_server_job(JobName)

                        elif UserCommand == "disable":
                            self.disable_server_job(JobName)

                        elif UserCommand == "build":
                            self.build_server_job(JobName)

                        elif UserCommand == 'stat *':
                            self.stat_server_job(JobName, Detail=True)

                        elif UserCommand == 'stat':
                            self.stat_server_job(JobName)

                        elif UserCommand == "":
                            pass
                        else:
                            print("%Invalid Command")

                    except KeyboardInterrupt:
                        break
                    except EOFError:
                        break
                    except:
                        print("There was a problem in program")
                        return

    def get_whoami(self):
        '''
        Display who is connected to server
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            UserInfo = self.ServerHandler.get_whoami()
            print("Full Name : ", UserInfo["fullName"])
            print("Id : ", UserInfo["id"])

    def asking_user_decision(self, displayMessage):
        '''
        This process is repeated many times in the code asking the user for yes/no answer
        so this process is turned into a function for simplicity

        :param displayMessage:  Message to be displayed for asking user his/her decision
        '''

        while True:
            UserDecision = input(displayMessage)
            if UserDecision.lower() in "y yes ye":
                return True
            elif UserDecision.lower() in "n no":
                return False

    def get_job_directory(self):
        return self.JCDirectoryLoc
Beispiel #19
0
                     db="devops")
# db.query("SELECT project FROM deployconfig WHERE deploy_type='vm'")
c = db.cursor()
c.execute("SELECT project FROM deployconfig WHERE deploy_type='vm'")

results = c.fetchall()
names = set()
print(results)
for item in results:
    # if item == "saas-factoring":
    names.add(item[0])

server = Jenkins('http://172.16.101.96:8080/',
                 username='******',
                 password='******')
jobs = server.get_jobs()
for i in jobs:
    # print(i['fullname'])
    tag = "Jenkinsfile-bak"
    full_name = i['fullname']
    if full_name in names:
        config = server.get_job_config(full_name)
        # if full_name == "check-account":
        #     print(config)
        result = re.search(r'<scriptId>(.*?)</scriptId>', config, re.M)
        if result:
            find = result.groups()[0]
            if find == "Jenkinsfile-Java-Business-Docker" or find == "Jenkinsfile-Java-Business":
                print(full_name, find)
                # if find == 'Jenkinsfile-bak':
                cc = config.replace(find, tag)
class JenkinsBot(BotPlugin):
    """Basic Err integration with Jenkins CI"""

    min_err_version = '1.2.1'

    # max_err_version = '3.3.0'

    def get_configuration_template(self):
        return CONFIG_TEMPLATE

    def configure(self, configuration):
        if configuration is not None and configuration != {}:
            config = dict(chain(CONFIG_TEMPLATE.items(),
                                configuration.items()))
        else:
            config = CONFIG_TEMPLATE
        super(JenkinsBot, self).configure(config)
        return

    def check_configuration(self, configuration):
        self.log.debug(configuration)
        for c in configuration:
            if c == 'URL':
                if not validators.url(configuration['URL']):
                    raise ValidationException(
                        'JENKINS_URL is not a well formed URL')
            elif c in ['USERNAME', 'PASSWORD', 'RECEIVE_NOTIFICATION']:
                if len(configuration[c]) == 0 or not isinstance(
                        configuration[c], str):
                    raise ValidationException(
                        "{} is a required string config setting".format(c))
            elif c in ['CHATROOMS_NOTIFICATION']:
                if not isinstance(configuration[c], tuple):
                    raise ValidationException(
                        "{} should be of type tuple".format(c))
        return

    def connect_to_jenkins(self):
        """Connect to a Jenkins instance using configuration."""
        self.log.debug('Connecting to Jenkins ({0})'.format(
            self.config['URL']))
        self.jenkins = Jenkins(url=self.config['URL'],
                               username=self.config['USERNAME'],
                               password=self.config['PASSWORD'])
        return

    def broadcast(self, mess):
        """Shortcut to broadcast a message to all elligible chatrooms."""
        chatrooms = (self.config['CHATROOMS_NOTIFICATION']
                     if self.config['CHATROOMS_NOTIFICATION'] else
                     self.bot_config.CHATROOM_PRESENCE)

        for room in chatrooms:
            self.send(self.build_identifier(room),
                      mess,
                      message_type='groupchat')
        return

    @webhook(r'/jenkins/notification')
    def handle_notification(self, incoming_request):
        if not self.config['RECEIVE_NOTIFICATION']:
            return "Notification handling is disabled \
                    (JENKINS_RECEIVE_NOTIFICATION = False)"

        self.log.debug(repr(incoming_request))
        self.broadcast(self.format_notification(incoming_request))
        return "OK"

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.connect_to_jenkins()
        return self.format_jobs(self.jenkins.get_jobs(folder_depth=None))

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.connect_to_jenkins()

        jobs = [
            job for job in self.jenkins.get_jobs() if 'anime' in job['color']
        ]
        return self.format_running_jobs(jobs)

    @botcmd(split_args_with=None)
    def jenkins_param(self, mess, args):
        """List Parameters for a given job."""
        if len(args) == 0:
            return 'What Job would you like the parameters for?'

        self.connect_to_jenkins()

        job = self.jenkins.get_job_info(args[0])
        if job['actions'][1] != {}:
            job_param = job['actions'][1]['parameterDefinitions']
        elif job['actions'][0] != {}:
            job_param = job['actions'][0]['parameterDefinitions']
        else:
            job_param = []

        return self.format_params(job_param)

    @botcmd(split_args_with=None)
    def jenkins_build(self, mess, args):
        """Build a Jenkins Job with the given parameters
        Example: !jenkins build test_project FOO:bar
        """
        if len(args) == 0:  # No Job name
            return 'What job would you like to build?'

        self.connect_to_jenkins()
        params = self.build_parameters(args[1:])

        # Is it a parameterized job ?
        job = self.jenkins.get_job_info(args[0])
        if job['actions'][0] == {} and job['actions'][1] == {}:
            self.jenkins.build_job(args[0])
        else:
            self.jenkins.build_job(args[0], params)

        running_job = self.search_job(args[0])
        return 'Your job should begin shortly: {0}'.format(
            self.format_jobs(running_job))

    @botcmd(split_args_with=None)
    def build(self, mess, args):
        """Shortcut for jenkins_build"""
        return self.jenkins_build(mess, args)

    @botcmd(split_args_with=None)
    def jenkins_create(self, mess, args):
        """Create a Jenkins Job.
        Example: !jenkins create pipeline foo [email protected]:foo/bar.git
        """
        if len(args) < 2:  # No Job type or name
            return 'Oops, I need a type and a name for your new job.'

        if args[0] not in ('pipeline', 'multibranch'):
            return 'I\'m sorry, what type of job do you want ?'

        self.connect_to_jenkins()

        if args[0] == 'pipeline':
            self.jenkins.create_job(
                args[1],
                JENKINS_JOB_TEMPLATE_PIPELINE.format(repository=args[2]))
        elif args[0] == 'multibranch':
            return
        return

    def search_job(self, search_term):
        self.log.debug('Querying Jenkins for job "{0}"'.format(search_term))
        return [
            job for job in self.jenkins.get_jobs(folder_depth=None)
            if search_term.lower() == job['fullname'].lower()
        ]

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return 'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join([
            '%s (%s)\n%s' % (job['name'], job['lastBuild']['url'],
                             job['healthReport'][0]['description'])
            for job in jobs_info
        ]).strip()

    @staticmethod
    def format_jobs(jobs):
        if len(jobs) == 0:
            return 'No jobs found.'

        max_length = max([len(job['fullname']) for job in jobs])
        return '\n'.join([
            '%s (%s)' % (job['fullname'].ljust(max_length), job['url'])
            for job in jobs
        ]).strip()

    @staticmethod
    def format_params(job):
        """Format job parameters."""
        if len(job) == 0:
            return 'This job is not parameterized.'
        PARAM_TEMPLATE = Template("""{% for p in params %}Type: {{p.type}}
Description: {{p.description}}
Default Value: {{p.defaultParameterValue.value}}
Parameter Name: {{p.name}}

{% endfor %}""")
        return PARAM_TEMPLATE.render({'params': job})

    @staticmethod
    def format_notification(body):
        body['fullname'] = body.get('fullname', body['name'])
        NOTIFICATION_TEMPLATE = Template("""Build #{{build.number}} \
{{build.status}} for Job {{fullname}} ({{build.full_url}})
{% if build.scm %}Based on {{build.scm.url}}/commit/{{build.scm.commit}} \
({{build.scm.branch}}){% endif %}""")
        return NOTIFICATION_TEMPLATE.render(body)

    @staticmethod
    def build_parameters(params):
        if len(params) > 0:
            return {
                param.split(':')[0]: param.split(':')[1]
                for param in params
            }
        return {'': ''}