1# -*- coding: utf-8 -*- # 2# Copyright 2019 Google Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15"""Flags for gcloud active-directory commands.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import unicode_literals 20 21from googlecloudsdk.api_lib.active_directory import exceptions 22from googlecloudsdk.calliope import arg_parsers 23from googlecloudsdk.calliope import base 24from googlecloudsdk.calliope.concepts import concepts 25from googlecloudsdk.command_lib.util.args import labels_util 26from googlecloudsdk.command_lib.util.concepts import concept_parsers 27 28VALID_REGIONS = [ 29 'asia-east1', 'asia-northeast1', 'asia-south1', 'asia-southeast1', 30 'australia-southeast1', 'europe-north1', 'europe-west1', 'europe-west2', 31 'europe-west3', 'europe-west4', 'northamerica-northeast1', 32 'southamerica-east1', 'us-central1', 'us-east1', 'us-east4', 'us-west1', 33 'us-west2' 34] 35 36 37def GetOperationResourceSpec(): 38 """Adds an operation resource spec.""" 39 return concepts.ResourceSpec( 40 'managedidentities.projects.locations.global.operations', 41 resource_name='operation', 42 disable_auto_completers=False, 43 projectsId=concepts.DEFAULT_PROJECT_ATTRIBUTE_CONFIG, 44 operationsId=OperationAttributeConfig(), 45 ) 46 47 48def OperationAttributeConfig(): 49 """Adds an operation attribute config.""" 50 return concepts.ResourceParameterAttributeConfig( 51 name='operation', 52 help_text='Name of the Managed Microsoft AD operation.', 53 ) 54 55 56def AddOperationResourceArg(parser, verb, positional=True): 57 """Adds an operation resource argument. 58 59 NOTE: May be used only if it's the only resource arg in the command. 60 61 Args: 62 parser: the argparse parser for the command. 63 verb: str, the verb to describe the resource, such as 'to update'. 64 positional: bool, if True, means that the instance ID is a positional rather 65 than a flag. 66 """ 67 name = 'NAME' if positional else '--operation' 68 concept_parsers.ConceptParser.ForResource( 69 name, 70 GetOperationResourceSpec(), 71 'The operation name {}.'.format(verb), 72 required=True).AddToParser(parser) 73 74 75# Flags for update domain. 76def AddRegionFlag(unused_domain_ref, args, patch_request): 77 """Adds region to domain.""" 78 if args.IsSpecified('add_region'): 79 locs = patch_request.domain.locations + [args.add_region] 80 locs = sorted(set(locs)) 81 patch_request.domain.locations = locs 82 AddFieldToUpdateMask('locations', patch_request) 83 return patch_request 84 85 86def RemoveRegionFlag(unused_domain_ref, args, patch_request): 87 """Removes region from domain.""" 88 if args.IsSpecified('remove_region'): 89 locs = [ 90 loc for loc in patch_request.domain.locations 91 if loc != args.remove_region 92 ] 93 locs = sorted(set(locs)) 94 if not locs: 95 raise exceptions.ActiveDirectoryError('Cannot remove all regions') 96 patch_request.domain.locations = locs 97 AddFieldToUpdateMask('locations', patch_request) 98 return patch_request 99 100 101def AddAuthorizedNetworksFlag(unused_domain_ref, args, patch_request): 102 """Adds authorized networks to domain.""" 103 if args.IsSpecified('add_authorized_networks'): 104 ans = patch_request.domain.authorizedNetworks + args.add_authorized_networks 105 ans = sorted(set(ans)) 106 patch_request.domain.authorizedNetworks = ans 107 AddFieldToUpdateMask('authorized_networks', patch_request) 108 return patch_request 109 110 111def RemoveAuthorizedNetworksFlag(unused_domain_ref, args, patch_request): 112 """Removes authorized networks from domain.""" 113 if args.IsSpecified('remove_authorized_networks'): 114 ans = [ 115 an for an in patch_request.domain.authorizedNetworks 116 if an not in args.remove_authorized_networks 117 ] 118 ans = sorted(set(ans)) 119 patch_request.domain.authorizedNetworks = ans 120 AddFieldToUpdateMask('authorized_networks', patch_request) 121 return patch_request 122 123 124def UpdateAuditLogsEnabled(unused_domain_ref, args, patch_request): 125 """Updates audit logs config for the domain.""" 126 if args.IsSpecified('enable_audit_logs'): 127 patch_request.domain.auditLogsEnabled = args.enable_audit_logs 128 AddFieldToUpdateMask('audit_logs_enabled', patch_request) 129 return patch_request 130 131 132def AddFieldToUpdateMask(field, patch_request): 133 """Adds name of field to update mask.""" 134 update_mask = patch_request.updateMask 135 if update_mask: 136 if update_mask.count(field) == 0: 137 patch_request.updateMask = update_mask + ',' + field 138 else: 139 patch_request.updateMask = field 140 return patch_request 141 142 143def AdditionalDomainUpdateArguments(): 144 """Adds all update domain arguments.""" 145 return DomainUpdateLabelsFlags() + [RegionUpdateFlags(), AuthNetUpdateFlags()] 146 147 148def RegionUpdateFlags(): 149 """Defines flags for updating regions.""" 150 region_group = base.ArgumentGroup(mutex=True) 151 region_group.AddArgument(DomainAddRegionFlag()) 152 region_group.AddArgument(DomainRemoveRegionFlag()) 153 return region_group 154 155 156def AuthNetUpdateFlags(): 157 """Defines flags for updating authorized networks.""" 158 auth_net_group = base.ArgumentGroup(mutex=True) 159 auth_net_group.AddArgument(DomainAddAuthorizedNetworksFlag()) 160 auth_net_group.AddArgument(DomainRemoveAuthorizedNetworksFlag()) 161 return auth_net_group 162 163 164def DomainUpdateLabelsFlags(): 165 """Defines flags for updating labels.""" 166 remove_group = base.ArgumentGroup(mutex=True) 167 remove_group.AddArgument(labels_util.GetClearLabelsFlag()) 168 remove_group.AddArgument(labels_util.GetRemoveLabelsFlag('')) 169 return [labels_util.GetUpdateLabelsFlag(''), remove_group] 170 171 172def RegionsType(value): 173 """Defines valid GCP regions.""" 174 return arg_parsers.ArgList(choices=VALID_REGIONS)(value) 175 176 177def DomainAddRegionFlag(): 178 """Defines a flag for adding a region.""" 179 return base.Argument( 180 '--add-region', 181 help="""\ 182 An additional region to provision this domain in. 183 If domain is already provisioned in region, nothing will be done in that 184 region. Supported regions are: {}. 185 """.format(', '.join(VALID_REGIONS))) 186 187 188def DomainRemoveRegionFlag(): 189 """Defines a flag for removing a region.""" 190 return base.Argument( 191 '--remove-region', 192 help="""\ 193 A region to de-provision this domain from. 194 If domain is already not provisioned in a region, nothing will be done in 195 that region. Domains must be left provisioned in at least one region. 196 Supported regions are: {}. 197 """.format(', '.join(VALID_REGIONS))) 198 199 200def DomainAddAuthorizedNetworksFlag(): 201 """Defines a flag for adding an authorized network.""" 202 return base.Argument( 203 '--add-authorized-networks', 204 metavar='AUTH_NET1, AUTH_NET2, ...', 205 type=arg_parsers.ArgList(), 206 action=arg_parsers.UpdateAction, 207 help="""\ 208 A list of URLs of additional networks to peer this domain to in the form 209 projects/{project}/global/networks/{network}. 210 Networks must belong to the project. 211 """) 212 213 214def DomainRemoveAuthorizedNetworksFlag(): 215 """Defines a flag for removing an authorized network.""" 216 return base.Argument( 217 '--remove-authorized-networks', 218 metavar='AUTH_NET1, AUTH_NET2, ...', 219 type=arg_parsers.ArgList(), 220 action=arg_parsers.UpdateAction, 221 help="""\ 222 A list of URLs of additional networks to unpeer this domain from in the 223 form projects/{project}/global/networks/{network}. 224 Networks must belong to the project. 225 """) 226