示例#1
0
    def run_deployment_script(self, custom_deploy_script):
        method = 'run_deployment_script'
        commons.print_msg(Cloud.clazz, method, 'begin')

        cmd = "./" + custom_deploy_script

        execute_custom_script = subprocess.Popen(cmd.split(),
                                                 shell=False,
                                                 stdout=subprocess.PIPE,
                                                 stderr=subprocess.STDOUT)

        while execute_custom_script.poll() is None:
            line = execute_custom_script.stdout.readline().decode(
                'utf-8').strip(' \r\n')
            commons.print_msg(Cloud.clazz, method, line)

        execute_custom_script_output, execute_custom_script_error = execute_custom_script.communicate(
            timeout=120)

        for line in execute_custom_script_output.splitlines():
            commons.print_msg(Cloud.clazz, method, line.decode("utf-8"))

        if execute_custom_script.returncode != 0:
            commons.print_msg(
                Cloud.clazz, method,
                "Failed calling {command}. Return code of {rtn}".format(
                    command=cmd, rtn=execute_custom_script.returncode),
                'ERROR')
            return False

        commons.print_msg(Cloud.clazz, method, 'end')

        return True
示例#2
0
    def find_deployable(self, file_ext, dir_to_look_in):
        method = 'find_deployable'
        commons.print_msg(Cloud.clazz, method, 'begin')

        commons.print_msg(
            Cloud.clazz, method,
            "Looking for a {ext} in {dir}".format(ext=file_ext,
                                                  dir=dir_to_look_in))

        deployable_files = commons.get_files_of_type_from_directory(
            file_ext.lower(), dir_to_look_in)

        if len(deployable_files) > 1:
            commons.print_msg(
                Cloud.clazz, method,
                "Found more than 1 artifact in {}".format(dir_to_look_in),
                'ERROR')
            # raise IOError('Found more than 1 artifact')
            exit(1)
        elif len(deployable_files) == 0:
            commons.print_msg(
                Cloud.clazz, method,
                "Could not find file of type {ext} in {dir}".format(
                    ext=file_ext, dir=dir_to_look_in), 'ERROR')
            # raise IOError('Found 0 artifacts')
            exit(1)

        commons.print_msg(Cloud.clazz, method, 'end')

        return deployable_files[0]
示例#3
0
    def _get_stopped_apps(self):
        method = '_get_stopped_apps'
        commons.print_msg(CloudFoundry.clazz, method, 'begin')

        cmd = "{path}cf apps | grep {proj}*-v\d*\.\d*\.\d* | grep stopped | awk '{{print $1}}'".format(
            path=CloudFoundry.path_to_cf,
            proj=self.config.project_name)

        stopped_apps = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # nosec

        get_stopped_apps_failed = False

        try:
            CloudFoundry.stopped_apps, errs = stopped_apps.communicate(timeout=60)

            for line in CloudFoundry.stopped_apps.splitlines():
                commons.print_msg(CloudFoundry.clazz, method, "App Already Stopped: {}".format(line.decode('utf-8')))

            if stopped_apps.returncode != 0:
                commons.print_msg(CloudFoundry.clazz, method, "Failed calling {command}. Return code of {rtn}".format(
                    command=cmd, rtn=stopped_apps.returncode), 'ERROR')
                get_stopped_apps_failed = True

        except TimeoutExpired:
            commons.print_msg(CloudFoundry.clazz, method, "Timed out calling {}".format(cmd), 'ERROR')
            get_stopped_apps_failed = True

        if get_stopped_apps_failed:
            stopped_apps.kill()
            os.system('stty sane')
            self._cf_logout()
            exit(1)

        commons.print_msg(CloudFoundry.clazz, method, 'end')
示例#4
0
    def _cf_logout(self):
        method = '_cf_logout'
        commons.print_msg(CloudFoundry.clazz, method, 'begin')

        cmd = "{}cf logout".format(CloudFoundry.path_to_cf)

        cf_logout = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

        logout_failed = False

        try:
            cf_logout_output, errs = cf_logout.communicate(timeout=30)

            for line in cf_logout_output.splitlines():
                commons.print_msg(CloudFoundry.clazz, method, line.decode('utf-8'))

            if cf_logout.returncode != 0:
                commons.print_msg(CloudFoundry.clazz, method, "Failed calling {command}. Return code of {rtn}"
                                  .format(command=cmd,
                                         rtn=cf_logout.returncode),
                                 'ERROR')
                logout_failed = True

        except TimeoutExpired:
            commons.print_msg(CloudFoundry.clazz, method, "Timed out calling {}".format(cmd), 'ERROR')
            logout_failed = True

        if logout_failed:
            cf_logout.kill()
            os.system('stty sane')
            exit(1)

        commons.print_msg(CloudFoundry.clazz, method, 'end')
示例#5
0
    def __init__(self, config_override=None):
        method = '__init__'
        commons.print_msg(SonarQube.clazz, method, 'begin')

        if config_override is not None:
            self.config = config_override

        commons.print_msg(SonarQube.clazz, method, 'end')
示例#6
0
 def get_artifact_url(self):
     method = "get_artifact_url"
     if len(self.artifactory_extensions) > 1:
         commons.print_msg(
             Artifactory.clazz, method,
             "You have more then one extension declared. Use 'get_urls_of "
             "artifacts' to get more then one url")
     return self._get_artifact_url(self.artifactory_extensions[0])
示例#7
0
 def _check_artifact_permissions(self, remove_resp, method):
     if remove_resp.status_code == 403:
         commons.print_msg(
             Artifactory.clazz, method,
             "Failed publishing to artifactory: {response}. \nArtifact version must "
             "be updated before publishing".format(
                 response=remove_resp.text), "ERROR")
         exit(1)
示例#8
0
    def __init__(self):
        method = '__init__'

        self.endpoint = self.config.settings.get('metrics', 'endpoint')
        commons.print_msg(self.clazz, method, "Metrics Endpoint {}".format(self.endpoint))

        self.prefix = self.config.settings.get('metrics', 'prefix')
        commons.print_msg(self.clazz, method, "Metrics Prefix {}".format(self.prefix))
示例#9
0
    def __init__(self, config_override=None):
        method = '__init__'
        commons.print_msg(Slack.clazz, method, 'begin')

        Slack.slack_url = os.getenv('SLACK_WEBHOOK_URL')

        if config_override is not None:
            self.config = config_override

        commons.print_msg(Slack.clazz, method, 'end')
示例#10
0
    def _verify_required_attributes(self):
        method = '_verfify_required_attributes'

        if not os.getenv('GCAPPENGINE_USER_JSON'):
            commons.print_msg(
                GCAppEngine.clazz, method,
                'Credentials not loaded.  Please define '
                'environment variable '
                '\'GCAPPENGINE_USER_JSON\'', 'ERROR')
            exit(1)
示例#11
0
    def tag_stories_in_commit(self, story_list):
        method = 'tag_stories_in_commit'
        commons.print_msg(Tracker.clazz, method, 'begin')

        for story in story_list:
            label = self.config.project_name + '-' + self.config.version_number

            self._add_label_to_tracker(story, label)

        commons.print_msg(Tracker.clazz, method, 'end')
示例#12
0
    def _ship_it_artifactory(self, name):
        method = '_ship_it_artifactory'
        commons.print_msg(ZipIt.clazz, method, 'begin')

        file_with_path = name.split('/')

        ar = Artifactory()
        ar.publish(file_with_path[-1], name)

        commons.print_msg(ZipIt.clazz, method, 'end')
示例#13
0
    def _refresh_tags(self):
        method = '_refresh_tags'
        commons.print_msg(GitHub.clazz, method, 'getting latest tags')

        pull_tags_cmd = "git pull --tags"
        pull_tags = subprocess.Popen(pull_tags_cmd.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

        pull_tags_outputs, pull_tags_errs = pull_tags.communicate(timeout=300)

        for tag_line in pull_tags_outputs.splitlines():
            commons.print_msg(GitHub.clazz, method, tag_line.decode("utf-8"))
示例#14
0
    def __init__(self, mode, name, contents):
        method = '__init__'
        commons.print_msg(ZipIt.clazz, method, 'begin')

        ZipIt.file_name = name

        if mode == 'artifactory':
            ZipIt.zip_contents = contents
            self._zip_it(name, contents)
            self._ship_it_artifactory(name)

        commons.print_msg(ZipIt.clazz, method, 'end')
示例#15
0
    def _verify_required_attributes(self):
        method = '_verify_required_attributes'

        try:
            # noinspection PyStatementEffect
            self.config.json_config['github']
            GitHub.url = self.config.json_config['github']['URL']
            GitHub.org = self.config.json_config['github']['org']
            GitHub.repo = self.config.json_config['github']['repo']
        except KeyError as e:
            commons.print_msg(GitHub.clazz, method, "The build config associated with github is missing, {}."
                              .format(e), 'ERROR')
            exit(1)
示例#16
0
    def __init__(self, config_override=None):
        method = '__init__'
        commons.print_msg(GCAppEngine.clazz, method, 'begin')

        if config_override is not None:
            self.config = config_override

        if os.environ.get('WORKSPACE'):  # for Jenkins
            GCAppEngine.path_to_google_sdk = os.environ.get('WORKSPACE') + '/'
        else:
            GCAppEngine.path_to_google_sdk = ""

        commons.print_msg(GCAppEngine.clazz, method, 'end')
示例#17
0
    def tag_stories_in_commit(self, story_list):
        method = 'tag_stories_in_commit'
        commons.print_msg(Jira.clazz, method, 'begin')

        self._create_version(self.config.project_name + '-' +
                             self.config.version_number)

        for story in story_list:
            label = self.config.project_name + '-' + self.config.version_number

            self._add_version_to_jira_story(story, label)

        commons.print_msg(Jira.clazz, method, 'end')
示例#18
0
    def __init__(self, config_override=None):
        method = '__init__'
        commons.print_msg(CloudFoundry.clazz, method, 'begin')

        if config_override is not None:
            self.config = config_override

        if os.environ.get('WORKSPACE'):  # for Jenkins
            CloudFoundry.path_to_cf = os.environ.get('WORKSPACE') + '/'
        else:
            CloudFoundry.path_to_cf = ""

        commons.print_msg(CloudFoundry.clazz, method, 'end')
示例#19
0
    def _determine_app_yml(self):
        method = '_determine_app_yml'
        commons.print_msg(GCAppEngine.clazz, method, 'begin')

        if os.path.isfile("app-{}.yml".format(self.config.build_env)):
            app_yaml = "app-{}.yml".format(self.config.build_env)
        elif os.path.isfile("{dir}/app-{env}.yml".format(
                dir=self.config.push_location, env=self.config.build_env)):
            app_yaml = "{dir}/app-{env}.yml".format(
                dir=self.config.push_location, env=self.config.build_env)
        elif os.path.isfile("app-{}.yaml".format(self.config.build_env)):
            app_yaml = "app-{}.yaml".format(self.config.build_env)
        elif os.path.isfile("{dir}/app-{env}.yaml".format(
                dir=self.config.push_location, env=self.config.build_env)):
            app_yaml = "{dir}/app-{env}.yaml".format(
                dir=self.config.push_location, env=self.config.build_env)
        else:
            commons.print_msg(
                GCAppEngine.clazz, method,
                "Failed to find app_yaml file app-{}.yml/yaml".format(
                    self.config.build_env), 'ERROR')
            exit(1)

        # noinspection PyUnboundLocalVariable
        commons.print_msg(GCAppEngine.clazz, method,
                          "Using app_yaml {}".format(app_yaml))

        commons.print_msg(GCAppEngine.clazz, method, 'end')

        return app_yaml
示例#20
0
    def download_cf_cli(self):
        method = '_download_cf_cli'
        commons.print_msg(CloudFoundry.clazz, method, 'begin')

        cmd = "where" if platform.system() == "Windows" else "which"
        rtn = subprocess.call([cmd, 'cf'])

        if rtn == 0:
            commons.print_msg(CloudFoundry.clazz, method,
                              'cf cli already installed')
        else:
            commons.print_msg(
                CloudFoundry.clazz, method,
                "cf CLI was not installed on this image. "
                "Downloading CF CLI from {}".format(
                    self.config.settings.get('cloudfoundry',
                                             'cli_download_path')))

            urllib.request.urlretrieve(
                self.config.settings.get('cloudfoundry',
                                         'cli_download_path'),  # nosec
                './cf-linux-amd64.tgz')
            tar = tarfile.open('./cf-linux-amd64.tgz')
            CloudFoundry.path_to_cf = "./"
            tar.extractall()
            tar.close()

        commons.print_msg(CloudFoundry.clazz, method, 'end')
示例#21
0
    def _get_artifact_url(self):
        method = "_get_artifact_url"

        commons.print_msg(GitHub.clazz, method, "begin")

        if GitHub.token is not None:
            headers = {'Content-type': cicommons.content_json, 'Accept': cicommons.content_json, 'Authorization': ('token ' + GitHub.token)}
        else:
            headers = {'Content-type': cicommons.content_json, 'Accept': cicommons.content_json}

        tag_information_url = GitHub.url.replace('\\', '/').rstrip('/') + '/' + self.org + '/' + self.repo + \
                              '/releases/tags/' + self.config.version_number

        commons.print_msg(GitHub.clazz, method, ("Retrieving Github information from " + tag_information_url))

        resp = requests.get(tag_information_url, headers=headers)

        if resp.status_code != 200:
            commons.print_msg(GitHub.clazz, method, ("Failed to access github tag information at " + tag_information_url + "\r\n Response: " + resp.text), "ERROR")
            exit(1)
        else:
            commons.print_msg(GitHub.clazz, method, resp.text)

        json_data = json.loads(resp.text)

        artifact_to_download = json_data['tarball_url']

        return artifact_to_download
示例#22
0
    def scan_code(self):
        method = 'scan_code'
        commons.print_msg(SonarQube.clazz, method, 'begin')

        retries = 0

        keep_retrying = True

        while keep_retrying:
            try:
                sleep_timer = 0

                if self.config.settings.has_section('project') and self.config.settings.has_option('project',
                                                                                                   'retry_sleep_interval'):
                    sleep_timer = int(self.config.settings.get('project', 'retry_sleep_interval'))

                if retries > 0:
                    time.sleep(sleep_timer * retries)

                self._submit_scan()
                keep_retrying = False
            except Exception:
                retries += 1

                if retries > 3:
                    commons.print_msg(SonarQube.clazz, method, 'Could not connect to Sonar.  Maximum number of retries '
                                                              'reached.', "ERROR")
                    keep_retrying = False
                    exit(1)
                else:
                    commons.print_msg(SonarQube.clazz, method, "Attempting retry number {}".format(retries), "WARN")

        commons.print_msg(SonarQube.clazz, method, 'end')
示例#23
0
    def get_all_semver_tags(self, need_snapshot=0, need_release=0, need_tag=None, need_base=False):
        method = "get_all_semver_tags"
        all_tags_output = self.get_all_tags_and_shas_from_github(need_snapshot=need_snapshot, need_release=need_release, need_tag=need_tag, need_base=need_base)

        all_tags = all_tags_output#.splitlines()
        tag_data = []

        for tag, _ in all_tags:
            try:
                tag_data.append(self.convert_semver_string_to_semver_tag_array(tag))
            except Exception:
                commons.print_msg(GitHub.clazz, method, "This tag didn't parse right skipping: {} ".format(tag))

        tag_data.sort(reverse=True)
        GitHub.all_tags_sorted = tag_data
        return tag_data
示例#24
0
    def _determine_push_location(self):
        method = '_determine_push_location'
        commons.print_msg(CloudFoundry.clazz, method, 'begin')

        if self.config.artifact_extension is None or self.config.artifact_extension in (
                'zip', 'tar', 'tar.gz'):
            # deployed from github directly or it's a zip, tar, tar.gz file
            return "-p " + self.config.push_location
        elif self.config.artifact_extension == 'docker':
            # -p flag not supported for Docker deployments
            return ""
        else:
            return "-p {dir}/{file}".format(dir=self.config.push_location,
                                            file=self.find_deployable(
                                                self.config.artifact_extension,
                                                self.config.push_location))
示例#25
0
    def write_metric(self, task, action):
        method = 'write_metric'
        commons.print_msg(self.clazz, method, 'begin')
        # try:
        #     message = "{0}.{1}.{2}.{3}.count {4} {5}\n".format(self.prefix, task, action, self.config.project_name,
        #                                                        1, int(time()))
        #     # resp = post(self.endpoint, message)
        #     #
        #     # if resp.status_code == 200:
        #     #     commons.print_msg(self.clazz, method, "Metrics Write {}".format(message))
        #     # else:
        #     #     commons.print_msg(self.clazz, method, 'Metrics Write Failed', 'ERROR')
        #
        # except socket.error as e:
        #     commons.print_msg(self.clazz, method, "Metrics Write Failed ()".format(e), 'ERROR')

        commons.print_msg(self.clazz, method, 'end')
示例#26
0
    def __init__(self, config_override=None, verify_repo=True):
        method = '__init__'
        commons.print_msg(GitHub.clazz, method, 'begin')

        # check if we provided an override
        if config_override is not None:
            self.config = config_override

        if verify_repo is True:
            self._load_github_token()

            #self._refresh_tags()

            self._verify_required_attributes()

            self._verify_repo_existence(GitHub.url, GitHub.org, GitHub.repo)

        commons.print_msg(GitHub.clazz, method, 'end')
示例#27
0
    def download_artifact(self, artifact_url, download_path):
        """
        Download the artifact from artifactory. Really just a save a url to a file method.
        :param artifact_url: obviously, the artifact url
        :param download_path: Where you want the file to go
        :return: nothing, exceptions raised if it fails
        """
        method = "download_artifact"
        try:
            with open(download_path, 'wb') as handle:
                response = requests.get(artifact_url, stream=True)
                if not response.ok:
                    response.raise_for_status()

                for block in response.iter_content(1024):
                    handle.write(block)

        except Exception as e:
            commons.print_msg(Artifactory.clazz, method, 'Failed to download {}'.format(artifact_url), 'ERROR')
            commons.print_msg(Artifactory.clazz, method, "URLError is {msg}".format(msg=e))
            raise ArtifactDownloadException(e)
示例#28
0
    def __init__(self, config_override=None):
        method = '__init__'
        commons.print_msg(ServiceNow.clazz, method, 'begin')

        if config_override is not None:
            self.config = config_override

        try:
            # below line is to maintain backwards compatibility since stanza was renamed
            servicenow_json_config = self.config.json_config['servicenow'] if 'servicenow' in self.config.json_config else \
                                  self.config.json_config['servicemanagement']["servicenow"]
        except KeyError as e:
            commons.print_msg(
                ServiceNow.clazz, method,
                "The build config associated with servicemanagement is missing key {}"
                .format(str(e)), 'ERROR')
            exit(1)

        # Check for servicenow url first in buildConfig, second try settings.ini
        try:
            # noinspection PyUnboundLocalVariable
            ServiceNow.servicenow_url = servicenow_json_config['url']
        except:
            if self.config.settings.has_section(
                    'servicenow') and self.config.settings.has_option(
                        'servicenow', 'url'):
                ServiceNow.servicenow_url = self.config.settings.get(
                    'servicenow', 'url')
            else:
                commons.print_msg(
                    ServiceNow.clazz, method,
                    'No service now url found in buildConfig or settings.ini.',
                    'ERROR')
                exit(1)
示例#29
0
    def _get_manual_deploy_links(self):
        method = '_get_manual_deploy_links'
        manual_deploy_environment_links = {}

        # Look for manual deploy links in the current environment stanza
        if 'manualDeployEnvs' in self.config.build_env_info:
            manual_deploy_links = self.config.build_env_info['manualDeployEnvs']

            commons.print_msg(Slack.clazz, method, "Publishing build links: {}".format(manual_deploy_links))

            # For each manual deploy environment, lookup the corresponding link for that environment stanza
            for manually_deploy_to_env in manual_deploy_links:
                try:
                    manual_deploy_environment_links[manually_deploy_to_env] = self.config.json_config['environments'][manually_deploy_to_env]['manualDeployLink']
                    if "?" in manual_deploy_environment_links:
                        manual_deploy_environment_links[manually_deploy_to_env] = manual_deploy_environment_links[manually_deploy_to_env] + "&"
                    else:
                        manual_deploy_environment_links[manually_deploy_to_env] = manual_deploy_environment_links[manually_deploy_to_env] + "?"

                    manual_deploy_environment_links[manually_deploy_to_env] = manual_deploy_environment_links[manually_deploy_to_env] + "VERSION=" + urllib.parse.quote_plus(self.config.version_number)
                except KeyError as e:
                    commons.print_msg(Slack.clazz, method, "Could not find manual deploy link: {}".format(e),
                                     'ERROR')

        else:
            commons.print_msg(Slack.clazz, method, 'No manual build links specified')

        return manual_deploy_environment_links
示例#30
0
    def deploy(self, force_deploy=False, manifest=None):
        method = 'deploy'
        commons.print_msg(CloudFoundry.clazz, method, 'begin')

        self._verify_required_attributes()

        self.download_cf_cli()

        self._cf_login_check()

        self._cf_login()

        self._check_cf_version()

        self._get_stopped_apps()

        self._get_started_apps(force_deploy)

        if manifest is None:
            manifest = self._determine_manifests()

        self._cf_push(manifest)

        if not os.getenv("AUTO_STOP"):
            self._stop_old_app_servers()

        if not force_deploy:
            # don't delete if force bc we want to ensure that there is always 1 non-started instance
            # for backup and force_deploy is used when you need to redeploy/replace an instance
            # that is currently running
            self._unmap_delete_previous_versions()

        commons.print_msg(CloudFoundry.clazz, method, 'DEPLOYMENT SUCCESSFUL')

        commons.print_msg(CloudFoundry.clazz, method, 'end')