214 lines
7.5 KiB
Python
214 lines
7.5 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2018 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""General utilties for Cloud Source commands."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from googlecloudsdk.api_lib.util import apis
|
|
from googlecloudsdk.core import exceptions
|
|
from googlecloudsdk.core import properties
|
|
from googlecloudsdk.core import resources
|
|
|
|
_API_NAME = 'sourcerepo'
|
|
_API_VERSION = 'v1'
|
|
|
|
_MESSAGES = apis.GetMessagesModule(_API_NAME, _API_VERSION)
|
|
|
|
|
|
class InvalidTopicError(exceptions.Error):
|
|
"""Raised when a topic cannot be found within the repo."""
|
|
|
|
|
|
def CreateProjectResource(args):
|
|
return resources.REGISTRY.Create(
|
|
'sourcerepo.projects',
|
|
projectsId=args.project or properties.VALUES.core.project.GetOrFail())
|
|
|
|
|
|
def CreateTopicResource(topic_name, topic_project):
|
|
return resources.REGISTRY.Create(
|
|
'pubsub.projects.topics',
|
|
projectsId=topic_project,
|
|
topicsId=topic_name,
|
|
)
|
|
|
|
|
|
def ParseProjectConfigWithPushblock(args):
|
|
project_ref = CreateProjectResource(args)
|
|
project_name = project_ref.RelativeName()
|
|
|
|
enable_pushblock = args.enable_pushblock
|
|
return _MESSAGES.ProjectConfig(
|
|
enablePrivateKeyCheck=enable_pushblock,
|
|
name=project_name,
|
|
pubsubConfigs=None # No need to specify when only update key check.
|
|
)
|
|
|
|
|
|
def ParseSourceRepoWithModifiedTopic(args, repo):
|
|
"""Parse and create a new Repo message with modified topic."""
|
|
topic_name = GetTopicName(args)
|
|
if args.add_topic:
|
|
new_config = _ParsePubsubConfig(topic_name, args.message_format,
|
|
args.service_account)
|
|
return _AddTopicToResource(
|
|
topic_name, new_config, repo, resource_name='repo')
|
|
elif args.remove_topic:
|
|
return _RemoveTopicFromResource(topic_name, repo, resource_name='repo')
|
|
elif args.update_topic:
|
|
return _UpdateTopicInResource(topic_name, args, repo, resource_name='repo')
|
|
|
|
return repo
|
|
|
|
|
|
def ParseProjectConfigWithModifiedTopic(args, project_config):
|
|
"""Parse and create a new ProjectConfig message with modified topic."""
|
|
topic_name = GetTopicName(args)
|
|
if args.add_topic:
|
|
new_config = _ParsePubsubConfig(topic_name, args.message_format,
|
|
args.service_account)
|
|
return _AddTopicToResource(
|
|
topic_name, new_config, project_config, resource_name='project')
|
|
elif args.remove_topic:
|
|
return _RemoveTopicFromResource(
|
|
topic_name, project_config, resource_name='project')
|
|
elif args.update_topic:
|
|
return _UpdateTopicInResource(
|
|
topic_name, args, project_config, resource_name='project')
|
|
|
|
return project_config
|
|
|
|
|
|
def GetTopicName(args):
|
|
"""Get the topic name based on project and topic_project flags."""
|
|
if args.add_topic:
|
|
topic_ref = args.CONCEPTS.add_topic.Parse()
|
|
elif args.remove_topic:
|
|
topic_ref = args.CONCEPTS.remove_topic.Parse()
|
|
else:
|
|
topic_ref = args.CONCEPTS.update_topic.Parse()
|
|
|
|
return topic_ref.RelativeName()
|
|
|
|
|
|
def _AddTopicToResource(topic_name, new_config, resource, resource_name):
|
|
"""Add the PubsubConfig message to Repo/ProjectConfig message."""
|
|
if resource.pubsubConfigs is None:
|
|
config_additional_properties = []
|
|
else:
|
|
config_additional_properties = resource.pubsubConfigs.additionalProperties
|
|
|
|
resource_msg_module = _MESSAGES.ProjectConfig
|
|
if resource_name == 'repo':
|
|
resource_msg_module = _MESSAGES.Repo
|
|
|
|
config_additional_properties.append(
|
|
resource_msg_module.PubsubConfigsValue.AdditionalProperty(
|
|
key=topic_name, value=new_config))
|
|
|
|
return resource_msg_module(
|
|
name=resource.name,
|
|
pubsubConfigs=resource_msg_module.PubsubConfigsValue(
|
|
additionalProperties=config_additional_properties))
|
|
|
|
|
|
def _RemoveTopicFromResource(topic_name, resource, resource_name):
|
|
"""Remove the topic from the Repo/ProjectConfig message."""
|
|
if resource.pubsubConfigs is None:
|
|
raise InvalidTopicError('Invalid topic [{0}]: No topics are configured '
|
|
'in the {1}.'.format(topic_name, resource_name))
|
|
|
|
config_additional_properties = resource.pubsubConfigs.additionalProperties
|
|
for i, config in enumerate(config_additional_properties):
|
|
if config.key == topic_name:
|
|
del config_additional_properties[i]
|
|
break
|
|
else:
|
|
raise InvalidTopicError('Invalid topic [{0}]: You must specify a '
|
|
'topic that is already configured in the {1}.'
|
|
.format(topic_name, resource_name))
|
|
|
|
resource_msg_module = _MESSAGES.ProjectConfig
|
|
if resource_name == 'repo':
|
|
resource_msg_module = _MESSAGES.Repo
|
|
|
|
return resource_msg_module(
|
|
name=resource.name,
|
|
pubsubConfigs=resource_msg_module.PubsubConfigsValue(
|
|
additionalProperties=config_additional_properties))
|
|
|
|
|
|
def _UpdateTopicInResource(topic_name, args, resource, resource_name):
|
|
"""Update the topic in the configuration and return a new repo message."""
|
|
|
|
if resource.pubsubConfigs is None:
|
|
raise InvalidTopicError('Invalid topic [{0}]: No topics are configured '
|
|
'in the {1}.'.format(topic_name, resource_name))
|
|
|
|
config_additional_properties = resource.pubsubConfigs.additionalProperties
|
|
for i, config in enumerate(config_additional_properties):
|
|
if config.key == topic_name:
|
|
config_additional_properties[i].value = _UpdateConfigWithArgs(
|
|
config.value, args)
|
|
break
|
|
else:
|
|
raise InvalidTopicError('Invalid topic [{0}]: You must specify a '
|
|
'topic that is already configured in the {1}.'
|
|
.format(topic_name, resource_name))
|
|
|
|
resource_msg_module = _MESSAGES.ProjectConfig
|
|
if resource_name == 'repo':
|
|
resource_msg_module = _MESSAGES.Repo
|
|
|
|
return resource_msg_module(
|
|
name=resource.name,
|
|
pubsubConfigs=resource_msg_module.PubsubConfigsValue(
|
|
additionalProperties=config_additional_properties))
|
|
|
|
|
|
def _ParsePubsubConfig(topic_name, message_format=None, service_account=None):
|
|
"""Parse and create PubsubConfig message."""
|
|
message_format_enums = _MESSAGES.PubsubConfig.MessageFormatValueValuesEnum
|
|
if message_format == 'protobuf':
|
|
parsed_message_format = message_format_enums.PROTOBUF
|
|
else:
|
|
# By default, the message format is 'json'.
|
|
parsed_message_format = message_format_enums.JSON
|
|
|
|
return _MESSAGES.PubsubConfig(
|
|
messageFormat=parsed_message_format,
|
|
serviceAccountEmail=service_account,
|
|
topic=topic_name)
|
|
|
|
|
|
def _GetMessageFormatString(pubsub_config):
|
|
message_format_type = getattr(pubsub_config, 'messageFormat')
|
|
message_format_enums = _MESSAGES.PubsubConfig.MessageFormatValueValuesEnum
|
|
if message_format_type == message_format_enums.PROTOBUF:
|
|
return 'protobuf'
|
|
|
|
return 'json'
|
|
|
|
|
|
def _UpdateConfigWithArgs(pubsub_config, args):
|
|
message_format = args.message_format or _GetMessageFormatString(pubsub_config)
|
|
service_account = args.service_account or getattr(pubsub_config,
|
|
'serviceAccountEmail')
|
|
topic_name = pubsub_config.topic
|
|
|
|
return _ParsePubsubConfig(topic_name, message_format, service_account)
|