예제 #1
0
    def build_gcloud_deploy_args(self, component, source_path):

        config = component.descriptor['cloud_function']

        env_vars = config.get('environment_variables', {})
        env_vars_str = ("" if not env_vars else "--set-env-vars=" + ",".join(
            ["{}={}".format(key, value) for key, value in env_vars.items()]))

        template_version = util.encode_version(component.code_version)

        trigger_event = config['trigger_event'] \
            if 'trigger_event' in config else 'providers/cloud.pubsub/eventTypes/topic.publish'
        service_account = '--service-account {}'.format(config['service_account']) \
            if 'service_account' in config else ''
        vpc_connector = '--vpc-connector {}'.format(config['vpc_connector']) \
            if 'vpc_connector' in config else ''

        cmd = """
            gcloud functions deploy {cloud_function_name} \
                            --runtime {runtime} \
                            --memory {memory} \
                            --source {source_path} \
                            --timeout {timeout} \
                            --update-labels='code_version={version}' \
                            --trigger-event {trigger_event} \
                            --trigger-resource {topic} \
                            --entry-point {entrypoint} \
                            --project {project_id} \
                            {retry} \
                            {service_account} \
                            {vpc_connector} \
                            {env_vars_str}
            """.format(cloud_function_name=component.name,
                       runtime=config['runtime'],
                       timeout=config['timeout'],
                       memory=config['memory'],
                       trigger_event=trigger_event,
                       source_path=source_path,
                       version=util.encode_version(component.code_version),
                       retry="--retry" if config['retry'] else '',
                       service_account=service_account,
                       vpc_connector=vpc_connector,
                       entrypoint=config['entrypoint'],
                       topic=config['topic'],
                       project_id=self.project_id,
                       env_vars_str=env_vars_str).strip()

        return self.prettify_output(cmd)
예제 #2
0
    def build_gcloud_deploy_args(self, component, tmp_cloud_init_path, session, delete_template = False):
        template_version = util.encode_version(component.code_version)
        service_name = self.build_service_version_name(component)

        gcloud_args = []

        if delete_template and self._check_if_instance_template_exists(service_name, session):
            gcloud_args.append(self._delete_instance_template(
                                        component,
                                        template_version,
                                        service_name ))

        gcloud_args.append(self._create_instance_template(
                                        component,
                                        tmp_cloud_init_path,
                                        template_version,
                                        service_name ))

        instance_group = self._get_instance_group(component, session)
        if instance_group:
            gcloud_args.append(self._update_instance_group_if_needed(component, instance_group))
            gcloud_args.append(self._rolling_update_instance_template(component, service_name, instance_group))
        else:
            gcloud_args.append(self._create_instance_group(component, service_name))
            gcloud_args.append(self._attach_load_balancer_to_instance_group(component))

        return [self.prettify_output(arg) for arg in gcloud_args]
예제 #3
0
    def build_gcloud_deploy_args(self, component):
        config = component.descriptor['cloud_run']

        env_vars = config.get('environment_variables', {})
        env_vars_str = ("" if not env_vars else "--set-env-vars=" + ",".join(
            ["{}={}".format(key, value) for key, value in env_vars.items()]))
        base_args = """
            gcloud beta run deploy {cloud_run_service_name} \
                --memory={memory} \
                --timeout={timeout} \
                --update-labels='code_version={version}' \
                --project={project_id} \
                --region={region} \
                --service-account={service_account} \
                --platform={platform} \
                --no-allow-unauthenticated \
                {env_vars_str}
        """.format(cloud_run_service_name=component.name,
                   timeout=config['timeout'],
                   memory=config['memory'],
                   version=util.encode_version(component.code_version),
                   service_account=config['service_account'],
                   platform=config['platform'],
                   region=config['region'],
                   project_id=self.project_id,
                   env_vars_str=env_vars_str).strip()

        # Add image argument
        extra_args = self.gcloud_extra_args(component)
        cmd = base_args + " " + " ".join(extra_args)

        return self.prettify_output(cmd)
예제 #4
0
    def get_deployment_uri(self, component, versioned=False):
        host_prefix = '{app_name}-dot-{project_id}'.format(
                app_name = component.name,
                project_id = self.project_id)

        if versioned:
            encoded_version = util.encode_version(component.code_version)
            host_prefix = encoded_version + '-dot-' + host_prefix

        return 'https://' + host_prefix + '-dot-us-central1.etsycloud.com'
예제 #5
0
    def build_gcloud_deploy_args(self, component):
        extra_args = self.gcloud_extra_args(component)
        app_version = util.encode_version(component.code_version)

        base_args = [
            'gcloud', 'app', 'deploy', '--project', self.project_id,
            '--version', app_version
        ]

        return base_args + extra_args
예제 #6
0
 def build_service_version_name(cls, component):
     template_version = util.encode_version(component.code_version)
     timestamp = int(time.time()*1000)
     # The full instance group name may only be up to 61 characters long
     # The timestamp and the hyphen before it are 14 characters, so the
     # service name and version can be no longer than 47 characters
     name_and_version = "{}-{}".format(component.name, template_version)
     if len(name_and_version) > 47:
         name_and_version_hash = sha1(name_and_version.encode("utf-8")).hexdigest()[:6]
         name_and_version = name_and_version[:40] + "-" + name_and_version_hash
     return "{}-{}".format(name_and_version, timestamp).lower()
예제 #7
0
 def _delete_service_versions(self, service, versions):
     subprocess.check_call([
         'gcloud',
         'app',
         'versions',
         'delete',
         '--project',
         self.project_id,
         '--service',
         service,
         '--quiet',
     ] + [util.encode_version(v) for v in versions])
예제 #8
0
    def _build_labels(self, component):
        result = DataflowServiceVersion.build_labels(
            component_name=component.name,
            code_version=util.encode_version(component.code_version))

        user_labels = component.descriptor['dataflow'].get('labels', {})
        invalid_labels = [key for key in user_labels if key in result]
        if invalid_labels:
            raise Exception(
                'Invalid use of reserved labels `{}`'.format(invalid_labels))

        result.update(user_labels)

        return result
예제 #9
0
    def _deploy_with_rendered_app_yaml(self, component, rendered_app_yaml,
                                       workdir, dry_run):

        logging.info('Deploying app %s:%s', component.name,
                     util.encode_version(component.code_version))

        with open(os.path.join(workdir, 'app.yaml'), 'w') as _out:
            _out.write(rendered_app_yaml)

        gcloud_args = self.build_gcloud_deploy_args(component)

        if dry_run:
            logging.info(
                '  dry run: Skipping execution of gcloud command `%s`',
                ' '.join(gcloud_args))
            return

        else:
            subprocess.check_call(gcloud_args, cwd=workdir)
예제 #10
0
    def get_deployment_uri(self, component, versioned=False):
        host_prefix = '{app_name}-dot-{project_id}'.format(
            app_name=self.build_app_name(component),
            project_id=self.project_id)

        if versioned:
            encoded_version = util.encode_version(component.code_version)
            host_prefix = encoded_version + '-dot-' + host_prefix

        # I _think_ the maximum length for this is 63, but let's be a little conservative
        if len(host_prefix) > 60:
            # TODO: This is an extremely unlikely case, and may only be possible
            # if versioned==True, but we could handle it by checking the GAE API
            # to try to determine the proper hostname directly
            raise Exception(('Host prefix {} is too long (length is {})'
                             ', I think this will cause problems...').format(
                                 len(host_prefix)))

        return 'https://' + host_prefix + '.appspot.com'
예제 #11
0
 def _build_job_name(self, component):
     return component.name + '-' + util.encode_version(
         component.code_version) + '-' + self._random_hash(4)