def GenerateBackendService(context): """Generates one backendService resource.""" prop = context.properties port = prop[default.PORT] health_path = prop[default.HEALTH_PATH] default_srv = prop[default.SERVICE] outputs = prop.setdefault(GENERATED_PROP, dict()) be_name = common.AutoName(context.env['name'], default.BACKEND_SERVICE) hc_name = common.AutoName(context.env['name'], default.HEALTHCHECK) # pyformat: disable resource = [ { 'name': hc_name, 'type': default.HEALTHCHECK, 'properties': { 'port': port, 'requestPath': health_path, } }, { 'name': be_name, 'type': default.BACKEND_SERVICE, 'properties': { 'port': port, 'portName': default_srv, 'backends': GenerateBackends(context), 'healthChecks': [common.Ref(hc_name)], 'generatedProperties': outputs } } ] # pyformat: enable return resource
def MakeVMName(context): """Generates the VM name.""" name = context.env['name'] prop = context.properties named = INSTANCE_NAME in prop return prop[INSTANCE_NAME] if named else common.AutoName(name, default.INSTANCE)
def CreateAutscaler(context, name, igm, cpu_usage, depends_on=None): prop = context.properties autoscaler_name = common.AutoName(name, default.AUTOSCALER) depends_on = depends_on cpu_usage = float(cpu_usage) / 100 resource = { 'name': autoscaler_name, 'metadata': { 'dependsOn': depends_on }, 'type': default.REGION_AUTOSCALER, 'properties': { 'target': '$(ref.' + igm + '.selfLink)', 'region': common.ZoneToRegion(prop.get("externalZone")), 'autoscalingPolicy': { 'minNumReplicas': int(prop.get("minInstances")), 'maxNumReplicas': int(prop.get("maxInstances")), 'cpuUtilization': { 'utilizationTarget': cpu_usage }, 'coolDownPeriodSec': 90 } } } return resource
def MakeVMName(context): """Generates the VM name.""" name = context.env["name"] prop = context.properties if INSTANCE_NAME in prop: return prop[INSTANCE_NAME] return common.AutoName(name, default.INSTANCE)
def GenerateAutscaledGroup(context, zone_dict): """Generate one autoscaled_group resource Dict with a passed zone.""" name = context.env['name'] project = context.env[PROJECT] prop = context.properties zone = zone_dict[default.ZONE] zone_abbrv = common.ShortenZoneName(zone) as_name = common.AutoName(name, default.AUTOSCALER, zone_abbrv) base_name = name + '-' + default.AKA[default.INSTANCE] igm_name = common.AutoName(name, default.IGM, zone_abbrv) max_num = zone_dict[MAX_NUM] project = context.env[default.PROJECT] size = zone_dict[SIZE] vm_template = prop[VM_TEMPLATE] # pyformat: disable resource = [{ 'name': igm_name, 'type': default.IGM, 'properties': { 'project': project, 'zone': zone, 'targetSize': size, 'baseInstanceName': base_name, 'instanceTemplate': vm_template } }, { 'name': as_name, 'type': default.AUTOSCALER, 'properties': { 'project': project, 'zone': zone, 'target': common.Ref(igm_name), 'autoscalingPolicy': { 'maxNumReplicas': max_num } } }] # pyformat: enable return resource
def GenerateGlobalForwardingRule(context, number): """Generates a Global Forwarding Rule with the passed name.""" name = context.env['name'] prop = context.properties protocol = prop[IP_PROTO] return { 'name': common.AutoName(name, default.GF_RULE, str(number)), 'type': default.GF_RULE, 'properties': { 'IPProtocol': protocol, 'portRange': prop[PORT], 'target': common.AutoRef(name, default.PROXY), } } # pyformat: disable
def GenerateBackends(context): """Generates dictionary of IGMs connected to a backeend service.""" name = context.env['name'] prop = context.properties replicas = prop[REPLICAS] backends = [] for zone_dict in replicas: short_abbrv = common.ShortenZoneName(zone_dict[default.ZONE]) ig_name = common.AutoName(name, default.IGM, short_abbrv) zone_dict[GEN_NAME] = ig_name backend = {'name': ig_name, 'group': common.RefGroup(ig_name)} backends.append(backend) prop[GENERATED_PROP][REPLICAS] = copy.deepcopy(replicas) return backends
def GenerateLoadBalancer(context): """Generates the urlMap and globalForwardingRule part of the LB.""" name = context.env['name'] prop = context.properties resource = [ { 'name': common.AutoName(name, default.URL_MAP), 'type': default.URL_MAP, 'properties': { 'defaultService': prop[DEFAULT_SERVICE], 'hostRules': prop[HOST_RULES], 'pathMatchers': prop[PATH_MATCHERS], } }, { 'name': common.AutoName(name, default.PROXY), 'type': default.PROXY, 'properties': { 'urlMap': common.AutoRef(name, default.URL_MAP), } }, ] # pyformat: disable return resource
def GenerateAutscaledGroup(context, name, instance_template, depends_on=None): prop = context.properties igm_name = common.AutoName(name, default.IGM) depends_on = depends_on resource = { 'name': igm_name, 'metadata': { 'dependsOn': depends_on }, 'type': default.REGION_IGM, 'properties': { 'region': common.ZoneToRegion(prop.get("externalZone")), 'baseInstanceName': name, 'instanceTemplate': '$(ref.' + instance_template + '.selfLink)', 'targetSize': prop.get("minInstances"), # 'autoHealingPolicies': [{ # 'initialDelaySec': 60 # }] } } return resource
def GenerateFirewall(context): """Generates a firewall if prop[ADD_FIREWALL] is true.""" name = context.env['name'] prop = context.properties src_ranges = prop[SRC_RANGES] add_firewall = prop[ADD_FIREWALL] instances = [] if add_firewall: # pyformat: disable instances.append({ 'name': common.AutoName(name, default.FIREWALL), 'type': default.FIREWALL, 'properties': { 'sourceRanges': src_ranges, 'allowed': [{ 'IPProtocol': prop[IP_PROTO], 'ports': [prop[PORT]], }], } }) # pyformat: enable return instances
def create_instance_template(context, name, nics, depends_on=None, gw_version=VERSIONS['R80.20-GW']): family = '-'.join(['check-point', gw_version, LICENSE]) formatter = common.DefaultFormatter() instance_template_name = common.AutoName(name, default.TEMPLATE) instance_template = { "type": default.TEMPLATE, "name": instance_template_name, 'metadata': { 'dependsOn': depends_on }, "properties": { "project": context.properties['project'], "properties": { "canIpForward": True, "disks": [{ "autoDelete": True, "boot": True, "deviceName": common.set_name_and_truncate( context.properties['deployment'], '-{}-boot'.format(name)), "index": 0, "initializeParams": { "diskType": context.properties['diskType'], "diskSizeGb": context.properties['bootDiskSizeGb'], "sourceImage": 'projects/%s/global/images/%s' % (PROJECT, images.IMAGES[family]) }, "kind": 'compute#attachedDisk', "mode": "READ_WRITE", "type": "PERSISTENT" }], "machineType": context.properties['machineType'], "networkInterfaces": nics, 'metadata': { "kind": 'compute#metadata', 'items': [{ 'key': 'startup-script', 'value': formatter.format(startup_script, **context.properties) }, { 'key': 'serial-port-enable', 'value': 'true' }] }, "scheduling": { "automaticRestart": True, "onHostMaintenance": "MIGRATE", "preemptible": False }, "serviceAccounts": [{ "email": "default", "scopes": [ "https://www.googleapis.com/" + "auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/pubsub", "https://www.googleapis.com/" + "auth/service.management.readonly", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append" ] }], "tags": { "items": [ 'x-chkp-management--{}'.format( context.properties['managementName']), 'x-chkp-template--{}'.format( context.properties['AutoProvTemplate']), 'checkpoint-gateway' ] } } } } tagItems = instance_template['properties']['properties']['tags']['items'] if context.properties['mgmtNIC'] == 'Ephemeral Public IP (eth0)': tagItems.append("x-chkp-ip-address--public") tagItems.append("x-chkp-management-interface--eth0") elif context.properties['mgmtNIC'] == 'Private IP (eth1)': tagItems.append("x-chkp-ip-address--private") tagItems.append("x-chkp-management-interface--eth1") if context.properties['networkDefinedByRoutes']: tagItems.append("x-chkp-topology-eth1--internal") tagItems.append("x-chkp-topology-settings-eth1" "--network-defined-by-routes") metadata = instance_template['properties']['properties']['metadata'] if context.properties['instanceSSHKey']: metadata['items'].append({ 'key': 'instanceSSHKey', 'value': context.properties['instanceSSHKey'] }) return instance_template
def GenerateComputeVM(context): """Generates one VM instance resource.""" prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) # Temporary alternative while multiple disks on creation is not allowed if disks: new_disks = prop.setdefault(default.DISK_RESOURCES, list()) disks, prop[DISK_RESOURCES] = GenerateDisks(context, disks, new_disks) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) network = prop.setdefault(NETWORK, DEFAULT_NETWORK) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([('items', [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) has_external_ip = prop.get(HAS_EXTERNAL_IP, DEFAULT_HAS_EXTERNAL_IP) static_ip = prop.get(STATIC_IP, DEFAULT_STATIC_IP) nat_ip = prop.get(NAT_IP, None) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env['name'], default.DISK, 'boot') disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) network = common.MakeGlobalComputeLink(context, default.NETWORK) subnetwork = '' if default.SUBNETWORK in prop: subnetwork = common.MakeSubnetworkComputeLink(context, default.SUBNETWORK) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] access_configs = [] if has_external_ip: access_config = {'name': default.EXTERNAL, 'type': default.ONE_NAT} access_configs.append(access_config) if static_ip and nat_ip: raise common.Error( 'staticIP=True and natIP cannot be specified at the same time') if static_ip: address_resource, nat_ip = MakeStaticAddress(vm_name, zone) resource.append(address_resource) if nat_ip: access_config['natIP'] = nat_ip else: if static_ip: raise common.Error( 'staticIP cannot be True when hasExternalIP is False') if nat_ip: raise common.Error( 'natIP must not be specified when hasExternalIP is False') network_interfaces = [] if subnetwork: network_interfaces.insert( 0, { 'network': network, 'subnetwork': subnetwork, 'accessConfigs': access_configs }) else: network_interfaces.insert(0, { 'network': network, 'accessConfigs': access_configs }) resource.insert( 0, { 'name': vm_name, 'type': default.INSTANCE, 'properties': { 'zone': zone, 'machineType': machine_type, 'canIpForward': can_ip_fwd, 'disks': disks, 'networkInterfaces': network_interfaces, 'tags': tags, 'metadata': metadata, } }) # Pass through any additional property to the VM if SERVICE_ACCOUNTS in prop: resource[0]['properties'].update( {SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) return resource
def GenerateComputeVM(context, create_disks_separately=True): """Generates one VM instance resource. Args: context: Template context dictionary. create_disks_separately: When true (default), all new disk resources are created as separate resources. This is legacy behaviour from when multiple disks creation was not allowed in the disks property. Returns: dictionary representing instance resource. """ prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) if disks: if create_disks_separately: # Legacy alternative from when multiple disks on creation were not allowed new_disks = prop.setdefault(default.DISK_RESOURCES, list()) SetDiskProperties(context, disks) disks, prop[DISK_RESOURCES] = GenerateDisks( context, disks, new_disks) else: # All new disks (except local ssd) must provide a sourceImage or existing # source. Add blank source image if non provided. SetDiskProperties(context, disks, add_blank_src_img=True) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) SetMetadataDefaults(metadata) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([("items", [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env["name"], default.DISK, "boot") disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] resource.insert( 0, { "name": vm_name, "type": default.INSTANCE, "properties": { "zone": zone, "machineType": machine_type, "canIpForward": can_ip_fwd, "disks": disks, "networkInterfaces": GetNetworkInterfaces(context), "tags": tags, "metadata": metadata, }, }, ) # Pass through any additional properties to the VM if SERVICE_ACCOUNTS in prop: resource[0]["properties"].update( {SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) if GUEST_ACCELERATORS in prop: for accelerators in prop[GUEST_ACCELERATORS]: accelerators["acceleratorType"] = common.MakeAcceleratorTypeLink( context, accelerators["acceleratorType"]) resource[0]["properties"].update( {GUEST_ACCELERATORS: prop[GUEST_ACCELERATORS]}) # GPUs cannot be attached to live migratable instances. See: # https://cloud.google.com/compute/docs/gpus/#restrictions resource[0]["properties"].update( {"scheduling": { "onHostMaintenance": "terminate" }}) return resource
def GenerateComputeVM(context): """Generates one VM instance resource.""" name = context.env['name'] prop = context.properties if SRCIMAGE not in prop: raise common.Error('"%s" is a mandatory property' % SRCIMAGE) boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) # Temporary alternative while multiple disks on creation is not allowed if disks: new_disks = prop.setdefault(default.DISK_RESOURCES, list()) disks, prop[DISK_RESOURCES] = GenerateDisks(context, disks, new_disks) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) network = prop.setdefault(NETWORK, DEFAULT_NETWORK) named = INSTANCE_NAME in prop provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([('items', [])])) vm_name = prop[INSTANCE_NAME] if named else common.AutoName( name, default.INSTANCE) zone = prop.setdefault(ZONE, DEFAULT_ZONE) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env['name'], default.DISK, 'boot') disk_size = (prop[BOOTDISKSIZE] if BOOTDISKSIZE in prop else DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, default.DISKTYPE) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) network = common.MakeGlobalComputeLink(context, default.NETWORK) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) # pyformat: disable resource = [{ 'name': vm_name, 'type': default.INSTANCE, 'properties': { 'zone': zone, 'machineType': machine_type, 'canIpForward': can_ip_fwd, 'disks': disks, 'networkInterfaces': [{ 'network': network, 'accessConfigs': [{ 'name': default.EXTERNAL, 'type': default.ONE_NAT }] }], 'tags': tags, 'metadata': metadata, } }] # pyformat: enable # Pass through any additional property to the VM if SERVICE_ACCOUNTS in prop: resource[0]['properties'].update( {SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) return resource
def GenerateComputeVM(context, create_disks_separately=True): """Generates one VM instance resource. Args: context: Template context dictionary. create_disks_separately: When true (default), all new disk resources are created as separate resources. This is legacy behaviour from when multiple disks creation was not allowed in the disks property. Returns: dictionary representing instance resource. """ prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) if disks: if create_disks_separately: # Legacy alternative from when multiple disks on creation were not allowed new_disks = prop.setdefault(default.DISK_RESOURCES, list()) SetDiskProperties(context, disks) disks, prop[DISK_RESOURCES] = GenerateDisks(context, disks, new_disks) else: # All new disks (except local ssd) must provide a sourceImage or existing # source. Add blank source image if non provided. SetDiskProperties(context, disks, add_blank_src_img=True) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) SetMetadataDefaults(metadata) network = prop.setdefault(NETWORK, DEFAULT_NETWORK) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([('items', [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) has_external_ip = prop.get(HAS_EXTERNAL_IP, DEFAULT_HAS_EXTERNAL_IP) static_ip = prop.get(STATIC_IP, DEFAULT_STATIC_IP) nat_ip = prop.get(NAT_IP, None) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env['name'], default.DISK, 'boot') disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) network = common.MakeGlobalComputeLink(context, default.NETWORK) subnetwork = '' if default.SUBNETWORK in prop: subnetwork = common.MakeSubnetworkComputeLink(context, default.SUBNETWORK) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] access_configs = [] if has_external_ip: access_config = {'name': default.EXTERNAL, 'type': default.ONE_NAT} access_configs.append(access_config) if static_ip and nat_ip: raise common.Error( 'staticIP=True and natIP cannot be specified at the same time') if static_ip: address_resource, nat_ip = MakeStaticAddress(vm_name, zone) resource.append(address_resource) if nat_ip: access_config['natIP'] = nat_ip else: if static_ip: raise common.Error('staticIP cannot be True when hasExternalIP is False') if nat_ip: raise common.Error( 'natIP must not be specified when hasExternalIP is False') network_interfaces = [] if subnetwork: network_interfaces.insert(0, { 'network': network, 'subnetwork': subnetwork, 'accessConfigs': access_configs }) else: network_interfaces.insert(0, { 'network': network, 'accessConfigs': access_configs }) resource.insert(0, { 'name': vm_name, 'type': default.INSTANCE, 'properties': { 'zone': zone, 'machineType': machine_type, 'canIpForward': can_ip_fwd, 'disks': disks, 'networkInterfaces': network_interfaces, 'tags': tags, 'metadata': metadata, } }) # Pass through any additional properties to the VM if SERVICE_ACCOUNTS in prop: resource[0]['properties'].update({SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) if GUEST_ACCELERATORS in prop: for accelerators in prop[GUEST_ACCELERATORS]: accelerators['acceleratorType'] = common.MakeAcceleratorTypeLink( context, accelerators['acceleratorType']) resource[0]['properties'].update( {GUEST_ACCELERATORS: prop[GUEST_ACCELERATORS]}) # GPUs cannot be attached to live migratable instances. See: # https://cloud.google.com/compute/docs/gpus/#restrictions resource[0]['properties'].update( {'scheduling': {'onHostMaintenance': 'terminate'}}) return resource
def generate_config(context): """Creates the gateway.""" prop = context.properties prop['cloudguardVersion'], _, prop['installationType'] = prop[ 'installationType'].partition(' ') prop['templateName'] = TEMPLATE_NAME prop['templateVersion'] = TEMPLATE_VERSION prop['allowUploadDownload'] = str(prop['allowUploadDownload']).lower() if not prop['managementGUIClientNetwork'] and prop['installationType'] in { 'Gateway and Management (Standalone)', 'Management only' }: raise Exception('Allowed GUI clients are required when installing ' 'a management server') for k in ['managementGUIClientNetwork']: prop.setdefault(k, '') resources = [] outputs = [] network_interfaces = [] external_ifs = [] zone = prop['zone'] deployment = context.env['deployment'] vm_name = set_name_and_truncate(deployment, '-vm') access_configs = [] if prop['externalIP'] != 'None': access_config = make_access_config(resources, vm_name, zone, 'Static' == prop['externalIP']) access_configs.append(access_config) external_ifs.append(0) prop['hasInternet'] = 'true' else: prop['hasInternet'] = 'false' network = common.MakeGlobalComputeLink(context, default.NETWORK) networks = {prop['network']} network_interface = { 'network': network, 'accessConfigs': access_configs, } if default.SUBNETWORK in prop: network_interface['subnetwork'] = common.MakeSubnetworkComputeLink( context, default.SUBNETWORK) network_interfaces.append(network_interface) for ifnum in range(1, prop['numAdditionalNICs'] + 1): net = prop.get(ADDITIONAL_NETWORK.format(ifnum)) subnet = prop.get(ADDITIONAL_SUBNET.format(ifnum)) ext_ip = prop.get(ADDITIONAL_EXTERNAL_IP.format(ifnum)) if not net or not subnet: raise Exception( 'Missing network parameters for interface {}'.format(ifnum)) if net in networks: raise Exception('Cannot use network "' + net + '" more than once') networks.add(net) net = ''.join([ default.COMPUTE_URL_BASE, 'projects/', context.env['project'], '/global/networks/', net ]) subnet = ''.join([ default.COMPUTE_URL_BASE, 'projects/', context.env['project'], '/regions/', common.ZoneToRegion(zone), '/subnetworks/', subnet ]) network_interface = { 'network': net, 'subnetwork': subnet, } if 'None' != ext_ip: external_ifs.append(ifnum) access_config = make_access_config(resources, vm_name, zone, 'Static' == ext_ip, ifnum + 1) access_configs = [access_config] network_interface['accessConfigs'] = access_configs if not prop.get('hasInternet') or 'false' == prop['hasInternet']: prop['hasInternet'] = 'true' network_interfaces.append(network_interface) for ifnum in range(prop['numAdditionalNICs'] + 1, MAX_NICS): prop.pop(ADDITIONAL_NETWORK.format(ifnum), None) prop.pop(ADDITIONAL_SUBNET.format(ifnum), None) prop.pop(ADDITIONAL_EXTERNAL_IP.format(ifnum), None) deployment_config = set_name_and_truncate(deployment, '-config') prop['config_url'] = ('https://runtimeconfig.googleapis.com/v1beta1/' + 'projects/' + context.env['project'] + '/configs/' + deployment_config) prop['config_path'] = '/'.join(prop['config_url'].split('/')[-4:]) prop['deployment_config'] = deployment_config tags = ATTRIBUTES[prop['installationType']]['tags'] uid = set_name_and_truncate( vm_name, '-' + password.GeneratePassword(8, False).lower()) if prop['installationType'] == 'Gateway only': prop['cloudguardVersion'] += '-GW' if not prop.get('sicKey'): prop['computed_sic_key'] = password.GeneratePassword(12, False) else: prop['computed_sic_key'] = prop['sicKey'] else: prop['computed_sic_key'] = 'N/A' outputs.append({ 'name': 'sicKey', 'value': prop['computed_sic_key'], }, ) if 'gw' in VERSIONS[prop['cloudguardVersion']]: license_name = "{}-{}".format(LICENSE, LICENCE_TYPE) else: license_name = LICENSE family = '-'.join( ['check-point', VERSIONS[prop['cloudguardVersion']], license_name]) formatter = common.DefaultFormatter() gw = { 'type': default.INSTANCE, 'name': vm_name, 'properties': { 'description': ATTRIBUTES[prop['installationType']]['description'], 'zone': zone, 'tags': { 'items': tags + [uid], }, 'machineType': common.MakeLocalComputeLink(context, default.MACHINETYPE), 'canIpForward': ATTRIBUTES[prop['installationType']]['canIpForward'], 'networkInterfaces': network_interfaces, 'disks': [{ 'autoDelete': True, 'boot': True, 'deviceName': common.AutoName(context.env['name'], default.DISK, 'boot'), 'initializeParams': { 'diskType': common.MakeLocalComputeLink(context, default.DISKTYPE), 'diskSizeGb': prop['bootDiskSizeGb'], 'sourceImage': 'projects/%s/global/images/%s' % (PROJECT, images.IMAGES[family]), }, 'type': 'PERSISTENT', }], 'metadata': { 'items': [ { 'key': 'startup-script', 'value': formatter.format(startup_script, **prop) }, ] }, 'serviceAccounts': [{ 'email': 'default', 'scopes': ['https://www.googleapis.com/auth/monitoring.write'], }] } } if (prop['externalIP'] != 'None') and ('Manual Configuration' != prop['installationType']): gw['properties']['serviceAccounts'][0]['scopes'].append( 'https://www.googleapis.com/auth/cloudruntimeconfig') resources.append({ 'name': deployment_config, 'type': 'runtimeconfig.v1beta1.config', 'properties': { 'config': deployment_config, 'description': ('Holds software readiness status ' 'for deployment {}').format(deployment), }, }) resources.append({ 'name': set_name_and_truncate(deployment, '-software'), 'type': 'runtimeconfig.v1beta1.waiter', 'metadata': { 'dependsOn': [], }, 'properties': { 'parent': '$(ref.' + deployment_config + '.name)', 'waiter': 'software', 'timeout': '1800s', 'success': { 'cardinality': { 'number': 1, 'path': 'status/success', }, }, 'failure': { 'cardinality': { 'number': 1, 'path': 'status/failure', }, }, }, }) if 'instanceSSHKey' in prop: gw['properties']['metadata']['items'].append({ 'key': 'instanceSSHKey', 'value': prop['instanceSSHKey'] }) if prop['generatePassword']: passwd = password.GeneratePassword(12, False) gw['properties']['metadata']['items'].append({ 'key': 'adminPasswordSourceMetadata', 'value': passwd }) else: passwd = '' resources.append(gw) netlist = list(networks) if GATEWAY in tags: for i in range(len(netlist)): network = netlist[i] fw_rule_name_prefix = set_name_and_truncate( '{}-{}'.format(deployment[:23], network[:18]), '-allow-all-to-chkp-{}'.format(i + 1)) firewall_rules = create_firewall_rules(prop, network, fw_rule_name_prefix) resources.extend(firewall_rules) elif MANAGEMENT in tags: for i in range(len(netlist)): network = netlist[i] source_ranges = prop['network_tcpSourceRanges'] tcp_enabled = prop['network_enableTcp'] gwNetwork_enabled = prop['network_enableGwNetwork'] gwNetwork_source_range = prop['network_gwNetworkSourceRanges'] if source_ranges and not tcp_enabled: raise Exception( 'Allowed source IP ranges for TCP traffic are provided ' 'but TCP not marked as allowed') if tcp_enabled and not source_ranges: raise Exception('Allowed source IP ranges for TCP traffic' ' are required when installing ' 'a management server') if not gwNetwork_enabled and gwNetwork_source_range: raise Exception('Gateway network source IP are provided but ' 'not marked as allowed.') if gwNetwork_enabled and not gwNetwork_source_range: raise Exception('Gateway network source IP is required in' ' MGMT deployment.') ranges_list = source_ranges.split(',') gw_network_list = gwNetwork_source_range.split(',') ranges = [] gw_net_ranges = [] for source_range in ranges_list: ranges.append(source_range.replace(" ", "")) for gw_net_range in gw_network_list: gw_net_ranges.append(gw_net_range.replace(" ", "")) if tcp_enabled: if gwNetwork_enabled: resources.append({ 'type': 'compute.v1.firewall', 'name': set_name_and_truncate( '{}-{}'.format(deployment[:23], network[:18]), '-gateways-to-management-{}'.format(i + 1)), 'properties': { 'network': 'global/networks/' + network, 'sourceRanges': list(set(gw_net_ranges + ranges)), 'sourceTags': [GATEWAY], 'targetTags': [uid], 'allowed': [ { 'IPProtocol': 'tcp', 'ports': ['257', '18191', '18210', '18264'] }, ], } }) resources.append({ 'type': 'compute.v1.firewall', 'name': set_name_and_truncate( '{}-{}'.format(deployment[:23], network[:18]), '-allow-gui-clients-{}'.format(i + 1)), 'properties': { 'network': 'global/networks/' + network, 'sourceRanges': list(set(ranges)), 'targetTags': [uid], 'allowed': [ { 'IPProtocol': 'tcp', 'ports': ['22', '443', '18190', '19009'] }, ], } }) fw_rule_name_prefix = set_name_and_truncate( '{}-{}'.format(deployment[:23], network[:18]), '-allow-all-to-chkp-{}'.format(i + 1)) firewall_rules = create_firewall_rules(prop, network, fw_rule_name_prefix, True, uid) resources.extend(firewall_rules) outputs += [{ 'name': 'deployment', 'value': deployment }, { 'name': 'project', 'value': context.env['project'] }, { 'name': 'vmName', 'value': vm_name, }, { 'name': 'vmId', 'value': '$(ref.%s.id)' % vm_name, }, { 'name': 'vmSelfLink', 'value': '$(ref.%s.selfLink)' % vm_name, }, { 'name': 'hasMultiExternalIPs', 'value': 0 < len(external_ifs) and external_ifs != [0], }, { 'name': 'additionalExternalIPs', 'value': ', '.join([('$(ref.{}.networkInterfaces[{}].' + 'accessConfigs[0].natIP)').format(vm_name, ifnum) for ifnum in external_ifs if ifnum]) }, { 'name': 'vmInternalIP', 'value': '$(ref.%s.networkInterfaces[0].networkIP)' % vm_name, }, { 'name': 'password', 'value': passwd }] return common.MakeResource(resources, outputs)
def GenerateComputeVM(context, create_disks_separately=True): """Generates one VM instance resource. Args: context: Template context dictionary. create_disks_separately: When true (default), all new disk resources are created as separate resources. This is legacy behaviour from when multiple disks creation was not allowed in the disks property. Returns: dictionary representing instance resource. """ prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) project = context.env[default.PROJECT] deployApiToGke = context.properties['deployApiToGke'] datashare_install_bucket_name = project + '-install-bucket' datashare_ingestion_bucket_name = project + '-cds-bucket' k8s_cluster_name = 'datashare-cluster-resource' # gce_service_account = context.properties['gceServiceAccount'] if disks: if create_disks_separately: # Legacy alternative from when multiple disks on creation were not allowed new_disks = prop.setdefault(default.DISK_RESOURCES, list()) SetDiskProperties(context, disks) disks, prop[DISK_RESOURCES] = GenerateDisks(context, disks, new_disks) else: # All new disks (except local ssd) must provide a sourceImage or existing # source. Add blank source image if non provided. SetDiskProperties(context, disks, add_blank_src_img=True) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) SetMetadataDefaults(metadata) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([('items', [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env['name'], default.DISK, 'boot') disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] resource.insert( 0, { 'name': vm_name, 'type': default.INSTANCE, 'metadata': { 'dependsOn': [ datashare_ingestion_bucket_name ] }, 'properties': { 'zone': zone, 'machineType': machine_type, 'canIpForward': can_ip_fwd, 'disks': disks, 'networkInterfaces': GetNetworkInterfaces(context), 'tags': tags, 'metadata': metadata, } }) if deployApiToGke: resource[0]['metadata']['dependsOn'].append(k8s_cluster_name) if context.properties['useRuntimeConfigWaiter']: configName = context.properties['waiterConfigName'] resource[0]['metadata']['dependsOn'].append(configName) resource[0]['metadata']['dependsOn'].append(datashare_install_bucket_name) # Pass through any additional properties to the VM if SERVICE_ACCOUNTS in prop: resource[0]['properties'].update({SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) if GUEST_ACCELERATORS in prop: for accelerators in prop[GUEST_ACCELERATORS]: accelerators['acceleratorType'] = common.MakeAcceleratorTypeLink( context, accelerators['acceleratorType']) resource[0]['properties'].update( {GUEST_ACCELERATORS: prop[GUEST_ACCELERATORS]}) # GPUs cannot be attached to live migratable instances. See: # https://cloud.google.com/compute/docs/gpus/#restrictions resource[0]['properties'].update( {'scheduling': {'onHostMaintenance': 'terminate'}}) return resource