From 3847dd0bc69c904f6d63bd91597fb01c39323a3b Mon Sep 17 00:00:00 2001 From: rivkas Date: Thu, 4 Jan 2024 11:51:13 +0200 Subject: [PATCH] gcp sync gitub gitlab --- .../c2d_deployment_configuration.json | 2 +- .../check-point-autoscale--byol.py | 35 ++- .../check-point-autoscale--byol.py.schema | 12 +- .../autoscale-byol/common.py | 261 +++++++++--------- .../autoscale-byol/default.py | 8 +- .../autoscale-byol/images.py | 66 ++--- .../autoscale-byol/password.py | 100 ++++--- .../c2d_deployment_configuration.json | 2 +- .../check-point-autoscale--payg.py | 35 ++- .../check-point-autoscale--payg.py.schema | 12 +- .../autoscale-payg/common.py | 261 +++++++++--------- .../autoscale-payg/default.py | 8 +- .../autoscale-payg/images.py | 66 ++--- .../autoscale-payg/password.py | 100 ++++--- .../ha-byol/c2d_deployment_configuration.json | 2 +- .../ha-byol/check-point-cluster--byol.py | 7 +- .../check-point-cluster--byol.py.schema | 8 +- gcp/deployment-packages/ha-byol/common.py | 261 +++++++++--------- gcp/deployment-packages/ha-byol/default.py | 8 +- gcp/deployment-packages/ha-byol/images.py | 66 ++--- gcp/deployment-packages/ha-byol/password.py | 100 ++++--- .../ha-payg/c2d_deployment_configuration.json | 2 +- .../ha-payg/check-point-cluster--payg.py | 7 +- .../check-point-cluster--payg.py.schema | 8 +- gcp/deployment-packages/ha-payg/common.py | 261 +++++++++--------- gcp/deployment-packages/ha-payg/default.py | 8 +- gcp/deployment-packages/ha-payg/images.py | 66 ++--- gcp/deployment-packages/ha-payg/password.py | 100 ++++--- .../c2d_deployment_configuration.json | 2 +- .../single-byol/check-point-vsec--byol.py | 5 +- .../check-point-vsec--byol.py.schema | 8 +- gcp/deployment-packages/single-byol/common.py | 261 +++++++++--------- .../single-byol/default.py | 8 +- gcp/deployment-packages/single-byol/images.py | 66 ++--- .../single-byol/password.py | 100 ++++--- .../c2d_deployment_configuration.json | 2 +- .../single-payg/check-point-vsec--payg.py | 12 +- .../check-point-vsec--payg.py.schema | 8 +- gcp/deployment-packages/single-payg/common.py | 261 +++++++++--------- .../single-payg/default.py | 8 +- gcp/deployment-packages/single-payg/images.py | 66 ++--- .../single-payg/password.py | 100 ++++--- 42 files changed, 1426 insertions(+), 1353 deletions(-) diff --git a/gcp/deployment-packages/autoscale-byol/c2d_deployment_configuration.json b/gcp/deployment-packages/autoscale-byol/c2d_deployment_configuration.json index b4f0de48..67d45592 100755 --- a/gcp/deployment-packages/autoscale-byol/c2d_deployment_configuration.json +++ b/gcp/deployment-packages/autoscale-byol/c2d_deployment_configuration.json @@ -1,6 +1,6 @@ { "defaultDeploymentType": "MULTI_VM", - "imageName": "check-point-r8110-gw-byol-mig-335-991001174-v20221113", + "imageName": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", "projectId": "checkpoint-public", "templateName": "nonexistent_template", "useSolutionPackage": "true" diff --git a/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py b/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py index f2f7194d..0c65f374 100755 --- a/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py +++ b/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py @@ -18,12 +18,12 @@ } TEMPLATE_NAME = 'autoscale' -TEMPLATE_VERSION = '20230319' +TEMPLATE_VERSION = '20231221' startup_script = ''' #cloud-config runcmd: - - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\""' + - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\"" "osVersion=\\"{osVersion}\\"" "MaintenanceModePassword=\\"{maintenanceMode}\\""' ''' @@ -101,7 +101,7 @@ def create_instance_template(context, name, nics, depends_on=None, - gw_version=VERSIONS['R81.10-GW']): + gw_version=VERSIONS['R81.20-GW']): if 'gw' in gw_version: license_name = "{}-{}".format(LICENSE, LICENCE_TYPE) else: @@ -203,7 +203,16 @@ def create_instance_template(context, 'value': context.properties['instanceSSHKey'] } ) - return instance_template + passwd = '' + if context.properties['generatePassword']: + passwd = password.GeneratePassword(12, False) + metadata['items'].append( + { + 'key': 'adminPasswordSourceMetadata', + 'value': passwd + } + ) + return instance_template, passwd def GenerateAutscaledGroup(context, name, @@ -302,12 +311,16 @@ def generate_config(context): prop['gatewayExternalIP'] = (prop['mgmtNIC'] == 'Ephemeral Public IP (eth0)') version_chosen = prop['autoscalingVersion'].split(' ')[0] + "-GW" + prop['osVersion'] = prop['autoscalingVersion'].split(' ')[0].replace( + ".", "") nics = create_nics(context) - gw_template = create_instance_template(context, - prop['deployment'], - nics, - depends_on=prop['gw_dependencies'], - gw_version=VERSIONS[version_chosen]) + gw_template, passwd = create_instance_template(context, + prop['deployment'], + nics, + depends_on=prop[ + 'gw_dependencies'], + gw_version=VERSIONS[ + version_chosen]) prop['resources'] += [gw_template] prop['igm_dependencies'] = [gw_template['name']] igm = GenerateAutscaledGroup(context, @@ -360,5 +373,9 @@ def generate_config(context): 'name': 'maxInstancesInt', 'value': str(int(prop['maxInstances'])) }, + { + 'name': 'password', + 'value': passwd + } ] return common.MakeResource(prop['resources'], prop['outputs']) diff --git a/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py.schema b/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py.schema index de3862a1..0c5117b2 100755 --- a/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py.schema +++ b/gcp/deployment-packages/autoscale-byol/check-point-autoscale--byol.py.schema @@ -21,6 +21,7 @@ required: - networkDefinedByRoutes - shell - enableMonitoring + - generatePassword properties: zone: @@ -166,7 +167,7 @@ properties: diskTypeProperty: diskType autoscalingVersion: type: string - default: R81.10 Autoscaling + default: R81.20 Autoscaling enum: - R80.40 Autoscaling - R81 Autoscaling @@ -189,6 +190,13 @@ properties: allowUploadDownload: type: boolean default: True + generatePassword: + type: boolean + default: False + maintenanceMode: + type: string + pattern: ^([a-z0-9A-Z.]{12,300}|)$ + default: '' shell: type: string default: /etc/cli.sh @@ -202,4 +210,6 @@ outputs: deployment: type: string project: + type: string + password: type: string \ No newline at end of file diff --git a/gcp/deployment-packages/autoscale-byol/common.py b/gcp/deployment-packages/autoscale-byol/common.py index e123c502..0a40d315 100755 --- a/gcp/deployment-packages/autoscale-byol/common.py +++ b/gcp/deployment-packages/autoscale-byol/common.py @@ -11,7 +11,7 @@ # 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. -"""Generic simple functions used for python based template generation.""" +"""Generic simple functions used for python based templage generation.""" import re import sys @@ -25,8 +25,8 @@ class Error(Exception): - """Common exception wrapper for template exceptions.""" - pass + """Common exception wrapper for template exceptions.""" + pass class DefaultFormatter(string.Formatter): @@ -37,6 +37,7 @@ class DefaultFormatter(string.Formatter): """ def __init__(self, default=''): self.default = default + def get_value(self, key, args, dict): if isinstance(key, str): return dict.get(key, self.default) @@ -49,214 +50,214 @@ def set_name_and_truncate(primary, secondary, maxlength=62): def AddDiskResourcesIfNeeded(context): - """Checks context if disk resources need to be added.""" - if default.DISK_RESOURCES in context.properties: - return context.properties[default.DISK_RESOURCES] - else: - return [] + """Checks context if disk resources need to be added.""" + if default.DISK_RESOURCES in context.properties: + return context.properties[default.DISK_RESOURCES] + else: + return [] def AutoName(base, resource, *args): - """Helper method to generate names automatically based on default.""" - auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) - if not RFC1035_RE.match(auto_name): - raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % - (auto_name, resource, RFC1035_RE.pattern)) - return auto_name + """Helper method to generate names automatically based on default.""" + auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) + if not RFC1035_RE.match(auto_name): + raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % + (auto_name, resource, RFC1035_RE.pattern)) + return auto_name def AutoRef(base, resource, *args): - """Helper method that builds a reference for an auto-named resource.""" - return Ref(AutoName(base, resource, *args)) + """Helper method that builds a reference for an auto-named resource.""" + return Ref(AutoName(base, resource, *args)) def OrderedItems(dict_obj): - """Convenient method to yield sorted iteritems of a dictionary.""" - keys = list(dict_obj.keys()) - keys.sort() - for k in keys: - yield (k, dict_obj[k]) + """Convenient method to yield sorted iteritems of a dictionary.""" + keys = list(dict_obj.keys()) + keys.sort() + for k in keys: + yield (k, dict_obj[k]) def ShortenZoneName(zone): - """Given a string that looks like a zone name, creates a shorter version.""" - geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] - geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] - coord = default.LOC[coord.lower()] - number = str(number) - letter = letter.lower() - return geo + '-' + coord + number + letter + """Given a string that looks like a zone name, creates a shorter version.""" + geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] + geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] + coord = default.LOC[coord.lower()] + number = str(number) + letter = letter.lower() + return geo + '-' + coord + number + letter def ZoneToRegion(zone): - """Derives the region from a zone name.""" - parts = zone.split('-') - if len(parts) != 3: - raise Error('Cannot derive region from zone "%s"' % zone) - return '-'.join(parts[:2]) + """Derives the region from a zone name.""" + parts = zone.split('-') + if len(parts) != 3: + raise Error('Cannot derive region from zone "%s"' % zone) + return '-'.join(parts[:2]) def FormatException(message): - """Adds more information to the exception.""" - message = ('Exception Type: %s\n' - 'Details: %s\n' - 'Message: %s\n') % (sys.exc_info()[0], - traceback.format_exc(), message) - return message + """Adds more information to the exception.""" + message = ('Exception Type: %s\n Details: %s\n' + 'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message) + return message def Ref(name): - return '$(ref.%s.selfLink)' % name + return '$(ref.%s.selfLink)' % name def RefGroup(name): - return '$(ref.%s.instanceGroup)' % name + return '$(ref.%s.instanceGroup)' % name def GlobalComputeLink(project, collection, name): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - collection, '/', name]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + collection, '/', name]) + def GlobalNetworkLink(project, network): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - default.NETWORKS, '/', network]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + default.NETWORKS, '/', network]) def LocalComputeLink(project, zone, key, value): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', - zone, '/', key, '/', value]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', + zone, '/', key, '/', value]) def ReadContext(context, prop_key): - return (context.env['project'], context.properties.get('zone', None), - context.properties[prop_key]) + return (context.env['project'], context.properties.get('zone', None), + context.properties[prop_key]) def MakeLocalComputeLink(context, key, zone=None): - if not zone: - project, zone, value = ReadContext(context, key) - else: - project, _, value = ReadContext(context, key) + if not zone: + project, zone, value = ReadContext(context, key) + else: + project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return LocalComputeLink(project, zone, key + 's', value) + if IsComputeLink(value): + return value + else: + return LocalComputeLink(project, zone, key + 's', value) def MakeGlobalComputeLink(context, key): - project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return GlobalComputeLink(project, key + 's', value) + project, _, value = ReadContext(context, key) + if IsComputeLink(value): + return value + else: + return GlobalComputeLink(project, key + 's', value) + def MakeRegionalSubnetworkLink(project, zone, subnet): - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', subnet]) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', subnet]) def MakeSubnetworkComputeLink(context, key): - project, zone, value = ReadContext(context, key) - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', value]) + project, zone, value = ReadContext(context, key) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', value]) def MakeFQHN(context, name): - return '%s.c.%s.internal' % (name, context.env['project']) + return '%s.c.%s.internal' % (name, context.env['project']) # TODO(victorg): Consider moving this method to a different file def MakeC2DImageLink(name, dev_mode=False): - if IsGlobalProjectShortcut(name) or name.startswith('http'): - return name - else: - if dev_mode: - return 'global/images/%s' % name + if IsGlobalProjectShortcut(name) or name.startswith('http'): + return name else: - return GlobalComputeLink(default.C2D_IMAGES, 'images', name) + if dev_mode: + return 'global/images/%s' % name + else: + return GlobalComputeLink(default.C2D_IMAGES, 'images', name) def IsGlobalProjectShortcut(name): - return name.startswith('projects/') or name.startswith('global/') + return name.startswith('projects/') or name.startswith('global/') def IsComputeLink(name): - return (name.startswith(default.COMPUTE_URL_BASE) or - name.startswith(default.REFERENCE_PREFIX)) + return (name.startswith(default.COMPUTE_URL_BASE) or + name.startswith(default.REFERENCE_PREFIX)) def GetNamesAndTypes(resources_dict): - return [(d['name'], d['type']) for d in resources_dict] + return [(d['name'], d['type']) for d in resources_dict] def SummarizeResources(res_dict): - """Summarizes the name of resources per resource type.""" - result = {} - for res in res_dict: - result.setdefault(res['type'], []).append(res['name']) - return result + """Summarizes the name of resources per resource type.""" + result = {} + for res in res_dict: + result.setdefault(res['type'], []).append(res['name']) + return result def ListPropertyValuesOfType(res_dict, prop, res_type): - """Lists all the values for a property of a certain type.""" - return [r['properties'][prop] for r in res_dict if r['type'] == res_type] + """Lists all the values for a property of a certain type.""" + return [r['properties'][prop] for r in res_dict if r['type'] == res_type] def MakeResource(resource_list, output_list=None): - """Wrapper for a DM template basic spec.""" - content = {'resources': resource_list} - if output_list: - content['outputs'] = output_list - return yaml.dump(content) + """Wrapper for a DM template basic spec.""" + content = {'resources': resource_list} + if output_list: + content['outputs'] = output_list + return yaml.dump(content) def TakeZoneOut(properties): - """Given a properties dictionary, removes the zone specific information.""" - - def _CleanZoneUrl(value): - value = value.split('/')[-1] if IsComputeLink(value) else value - return value - - for name in default.VM_ZONE_PROPERTIES: - if name in properties: - properties[name] = _CleanZoneUrl(properties[name]) - if default.ZONE in properties: - properties.pop(default.ZONE) - if default.BOOTDISK in properties: - properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) - if default.DISKS in properties: - for disk in properties[default.DISKS]: - # Don't touch references to other disks - if default.DISK_SOURCE in disk: - continue - if default.INITIALIZEP in disk: - disk_init = disk[default.INITIALIZEP] - if default.DISKTYPE in disk_init: - disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) + """Given a properties dictionary, removes the zone specific information.""" + + def _CleanZoneUrl(value): + value = value.split('/')[-1] if IsComputeLink(value) else value + return value + + for name in default.VM_ZONE_PROPERTIES: + if name in properties: + properties[name] = _CleanZoneUrl(properties[name]) + if default.ZONE in properties: + properties.pop(default.ZONE) + if default.BOOTDISK in properties: + properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) + if default.DISKS in properties: + for disk in properties[default.DISKS]: + # Don't touch references to other disks + if default.DISK_SOURCE in disk: + continue + if default.INITIALIZEP in disk: + disk_init = disk[default.INITIALIZEP] + if default.DISKTYPE in disk_init: + disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) def GenerateEmbeddableYaml(yaml_string): - # Because YAML is a space delimited format, we need to be careful about - # embedding one YAML document in another. This function takes in a string in - # YAML format and produces an equivalent YAML representation that can be - # inserted into arbitrary points of another YAML document. It does so by - # printing the YAML string in a single line format. Consistent ordering of - # the string is also guaranteed by using yaml.dump. - yaml_object = yaml.load(yaml_string) - dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) - return dumped_yaml + # Because YAML is a space delimited format, we need to be careful about + # embedding one YAML document in another. This function takes in a string in + # YAML format and produces an equivalent YAML representation that can be + # inserted into arbitrary points of another YAML document. It does so by + # printing the YAML string in a single line format. Consistent ordering of + # the string is also guaranteed by using yaml.dump. + yaml_object = yaml.load(yaml_string) + dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) + return dumped_yaml def FormatErrorsDec(func): - """Decorator to format exceptions if they get raised.""" + """Decorator to format exceptions if they get raised.""" - def FormatErrorsWrap(context): - try: - return func(context) - except Exception as e: - raise Error(FormatException(e.message)) + def FormatErrorsWrap(context): + try: + return func(context) + except Exception as e: + raise Error(FormatException(e.message)) - return FormatErrorsWrap + return FormatErrorsWrap diff --git a/gcp/deployment-packages/autoscale-byol/default.py b/gcp/deployment-packages/autoscale-byol/default.py index 0c7dd919..054d9e52 100755 --- a/gcp/deployment-packages/autoscale-byol/default.py +++ b/gcp/deployment-packages/autoscale-byol/default.py @@ -11,7 +11,7 @@ # 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. -"""Convenience module to hold default constants for C2D components. +"""Convinence module to hold default constants for C2D components. There should not be any logic in this module. Its purpose is to simplify analysis of commonly used GCP and properties names and identify the names @@ -23,7 +23,7 @@ # URL constants COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' -# Deployment Manager constructs +# Deploymen Manager constructs REFERENCE_PREFIX = '$(ref.' # Commonly used in properties namespace @@ -105,8 +105,8 @@ REGION_IGM = 'compute.v1.regionInstanceGroupManager' REGION_AUTOSCALER = 'compute.v1.regionAutoscaler' URL_MAP = 'compute.v1.urlMap' -VPC='compute.v1.network' -VPC_SUBNET='compute.v1.subnetwork' +VPC = 'compute.v1.network' +VPC_SUBNET = 'compute.v1.subnetwork' # Also Known As constants AKA = { diff --git a/gcp/deployment-packages/autoscale-byol/images.py b/gcp/deployment-packages/autoscale-byol/images.py index 34855e97..a452b68e 100755 --- a/gcp/deployment-packages/autoscale-byol/images.py +++ b/gcp/deployment-packages/autoscale-byol/images.py @@ -1,34 +1,34 @@ IMAGES = { - "check-point-r8120-payg": "check-point-r8120-payg-631-991001383-v20230907", - "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001383-v20230907", - "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001383-v20230907", - "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001383-v20230907", - "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001383-v20230907", - "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001383-v20230907", - "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001383-v20230907", - "check-point-r8120-byol": "check-point-r8120-byol-631-991001383-v20230907", - "check-point-r8110-payg": "check-point-r8110-payg-335-991001383-v20230907", - "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001383-v20230907", - "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001383-v20230907", - "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001383-v20230907", - "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001383-v20230907", - "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001383-v20230907", - "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001383-v20230907", - "check-point-r8110-byol": "check-point-r8110-byol-335-991001383-v20230907", - "check-point-r81-payg": "check-point-r81-payg-392-991001383-v20230907", - "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001383-v20230907", - "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001383-v20230907", - "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001383-v20230907", - "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001383-v20230907", - "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001383-v20230907", - "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001383-v20230907", - "check-point-r81-byol": "check-point-r81-byol-392-991001383-v20230907", - "check-point-r8040-payg": "check-point-r8040-payg-294-991001383-v20230907", - "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001383-v20230907", - "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001383-v20230907", - "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001383-v20230907", - "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001383-v20230907", - "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001383-v20230907", - "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001383-v20230907", - "check-point-r8040-byol": "check-point-r8040-byol-294-991001383-v20230907" -} + "check-point-r8120-payg": "check-point-r8120-payg-631-991001475-v20231221", + "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001475-v20231221", + "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", + "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", + "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001475-v20231221", + "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", + "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", + "check-point-r8120-byol": "check-point-r8120-byol-631-991001475-v20231221", + "check-point-r8110-payg": "check-point-r8110-payg-335-991001475-v20231221", + "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001475-v20231221", + "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001475-v20231221", + "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001475-v20231221", + "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001475-v20231221", + "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001475-v20231221", + "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001475-v20231221", + "check-point-r8110-byol": "check-point-r8110-byol-335-991001475-v20231221", + "check-point-r81-payg": "check-point-r81-payg-392-991001475-v20231221", + "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001475-v20231221", + "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001475-v20231221", + "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001475-v20231221", + "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001475-v20231221", + "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001475-v20231221", + "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001475-v20231221", + "check-point-r81-byol": "check-point-r81-byol-392-991001475-v20231221", + "check-point-r8040-payg": "check-point-r8040-payg-294-991001475-v20231221", + "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001475-v20231221", + "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001475-v20231221", + "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001475-v20231221", + "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001475-v20231221", + "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001475-v20231221", + "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001475-v20231221", + "check-point-r8040-byol": "check-point-r8040-byol-294-991001475-v20231221" +} \ No newline at end of file diff --git a/gcp/deployment-packages/autoscale-byol/password.py b/gcp/deployment-packages/autoscale-byol/password.py index 273210a6..bfe40f5c 100755 --- a/gcp/deployment-packages/autoscale-byol/password.py +++ b/gcp/deployment-packages/autoscale-byol/password.py @@ -63,73 +63,71 @@ class InputError(Exception): - """Raised when input properties are unexpected.""" + """Raised when input properties are unexpected.""" def GenerateConfig(context): - """Entry function to generate the DM config.""" - props = context.properties - length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) - include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) + """Entry function to generate the DM config.""" + props = context.properties + length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) + include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) - if not isinstance(include_symbols, bool): - raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) + if not isinstance(include_symbols, bool): + raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) - content = { + content = { 'resources': [], 'outputs': [{ 'name': 'password', 'value': GeneratePassword(length, include_symbols) }] - } - return yaml.dump(content) + } + return yaml.dump(content) def GeneratePassword(length=8, include_symbols=False): - """Generates a random password.""" - if length < MIN_LENGTH: - raise InputError('Password length must be at least %d' % MIN_LENGTH) - - candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols - else CANDIDATES_WITHOUT_SYMBOLS) - categories = (CATEGORIES_WITH_SYMBOLS if include_symbols - else CATEGORIES_WITHOUT_SYMBOLS) - - # Generates up to the specified length minus the number of categories. - # Then inserts one character for each category, ensuring that the character - # satisfy the category if the generated string hasn't already. - generated = ([random.choice(ALPHABET)] + - [random.choice(candidates) - for _ in range(length - 1 - len(categories))]) - for category in categories: - _InsertAndEnsureSatisfaction(generated, category, candidates) - return ''.join(generated) + """Generates a random password.""" + if length < MIN_LENGTH: + raise InputError('Password length must be at least %d' % MIN_LENGTH) + + candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols + else CANDIDATES_WITHOUT_SYMBOLS) + categories = (CATEGORIES_WITH_SYMBOLS if include_symbols + else CATEGORIES_WITHOUT_SYMBOLS) + + # Generates up to the specified length minus the number of categories. + # Then inserts one character for each category, ensuring that the character + # satisfy the category if the generated string hasn't already. + generated = ([random.choice(ALPHABET)] + [random.choice(candidates) + for _ in range(length - 1 - len(categories))]) + for category in categories: + _InsertAndEnsureSatisfaction(generated, category, candidates) + return ''.join(generated) def _InsertAndEnsureSatisfaction(generated, required, all_candidates): - """Inserts 1 char into generated, satisfying required if not already. - - If the required characters are not already in the generated string, one will - be inserted. If any required character is already in the generated string, a - random character from all_candidates will be inserted. The insertion happens - at a random location but not at the beginning. - - Args: - generated: the string to be modified. - required: list of required characters to check for. - all_candidates: list of characters to choose from if the required characters - are already satisfied. - """ - if set(generated).isdisjoint(required): - # Not yet satisfied. Insert a required candidate. - _InsertInto(generated, required) - else: - # Already satisfied. Insert any candidate. - _InsertInto(generated, all_candidates) + """Inserts 1 char into generated, satisfying required if not already. + + If the required characters are not already in the generated string, one will + be inserted. If any required character is already in the generated string, a + random character from all_candidates will be inserted. The insertion happens + at a random location but not at the beginning. + + Args: + generated: the string to be modified. + required: list of required characters to check for. + all_candidates: list of characters to choose from if the required characters + are already satisfied. + """ + if set(generated).isdisjoint(required): + # Not yet satisfied. Insert a required candidate. + _InsertInto(generated, required) + else: + # Already satisfied. Insert any candidate. + _InsertInto(generated, all_candidates) def _InsertInto(generated, candidates): - """Inserts a random candidate into a random non-zero index of generated.""" - # Avoids inserting at index 0, since the first character follows its own rule. - generated.insert(random.randint(1, len(generated) - 1), - random.choice(candidates)) + """Inserts a random candidate into a random non-zero index of generated.""" + # Avoids inserting at index 0, since the first character follows its own rule. + generated.insert(random.randint(1, len(generated) - 1), random.choice(candidates)) diff --git a/gcp/deployment-packages/autoscale-payg/c2d_deployment_configuration.json b/gcp/deployment-packages/autoscale-payg/c2d_deployment_configuration.json index a4e8a94a..4141cb87 100755 --- a/gcp/deployment-packages/autoscale-payg/c2d_deployment_configuration.json +++ b/gcp/deployment-packages/autoscale-payg/c2d_deployment_configuration.json @@ -1,6 +1,6 @@ { "defaultDeploymentType": "MULTI_VM", - "imageName": "check-point-r8110-gw-payg-mig-335-991001174-v20221113", + "imageName": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", "projectId": "checkpoint-public", "templateName": "nonexistent_template", "useSolutionPackage": "true" diff --git a/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py b/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py index bc27332e..05acbfdc 100755 --- a/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py +++ b/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py @@ -18,12 +18,12 @@ } TEMPLATE_NAME = 'autoscale' -TEMPLATE_VERSION = '20230319' +TEMPLATE_VERSION = '20231221' startup_script = ''' #cloud-config runcmd: - - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\""' + - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\"" "osVersion=\\"{osVersion}\\"" "MaintenanceModePassword=\\"{maintenanceMode}\\""' ''' @@ -101,7 +101,7 @@ def create_instance_template(context, name, nics, depends_on=None, - gw_version=VERSIONS['R81.10-GW']): + gw_version=VERSIONS['R81.20-GW']): if 'gw' in gw_version: license_name = "{}-{}".format(LICENSE, LICENCE_TYPE) else: @@ -203,7 +203,16 @@ def create_instance_template(context, 'value': context.properties['instanceSSHKey'] } ) - return instance_template + passwd = '' + if context.properties['generatePassword']: + passwd = password.GeneratePassword(12, False) + metadata['items'].append( + { + 'key': 'adminPasswordSourceMetadata', + 'value': passwd + } + ) + return instance_template, passwd def GenerateAutscaledGroup(context, name, @@ -302,12 +311,16 @@ def generate_config(context): prop['gatewayExternalIP'] = (prop['mgmtNIC'] == 'Ephemeral Public IP (eth0)') version_chosen = prop['autoscalingVersion'].split(' ')[0] + "-GW" + prop['osVersion'] = prop['autoscalingVersion'].split(' ')[0].replace( + ".", "") nics = create_nics(context) - gw_template = create_instance_template(context, - prop['deployment'], - nics, - depends_on=prop['gw_dependencies'], - gw_version=VERSIONS[version_chosen]) + gw_template, passwd = create_instance_template(context, + prop['deployment'], + nics, + depends_on=prop[ + 'gw_dependencies'], + gw_version=VERSIONS[ + version_chosen]) prop['resources'] += [gw_template] prop['igm_dependencies'] = [gw_template['name']] igm = GenerateAutscaledGroup(context, @@ -360,5 +373,9 @@ def generate_config(context): 'name': 'maxInstancesInt', 'value': str(int(prop['maxInstances'])) }, + { + 'name': 'password', + 'value': passwd + } ] return common.MakeResource(prop['resources'], prop['outputs']) diff --git a/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py.schema b/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py.schema index 071abd52..b3ab0980 100755 --- a/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py.schema +++ b/gcp/deployment-packages/autoscale-payg/check-point-autoscale--payg.py.schema @@ -21,6 +21,7 @@ required: - networkDefinedByRoutes - shell - enableMonitoring + - generatePassword properties: zone: @@ -166,7 +167,7 @@ properties: diskTypeProperty: diskType autoscalingVersion: type: string - default: R81.10 Autoscaling + default: R81.20 Autoscaling enum: - R80.40 Autoscaling - R81 Autoscaling @@ -189,6 +190,13 @@ properties: allowUploadDownload: type: boolean default: True + generatePassword: + type: boolean + default: False + maintenanceMode: + type: string + pattern: ^([a-z0-9A-Z.]{12,300}|)$ + default: '' shell: type: string default: /etc/cli.sh @@ -202,4 +210,6 @@ outputs: deployment: type: string project: + type: string + password: type: string \ No newline at end of file diff --git a/gcp/deployment-packages/autoscale-payg/common.py b/gcp/deployment-packages/autoscale-payg/common.py index e123c502..0a40d315 100755 --- a/gcp/deployment-packages/autoscale-payg/common.py +++ b/gcp/deployment-packages/autoscale-payg/common.py @@ -11,7 +11,7 @@ # 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. -"""Generic simple functions used for python based template generation.""" +"""Generic simple functions used for python based templage generation.""" import re import sys @@ -25,8 +25,8 @@ class Error(Exception): - """Common exception wrapper for template exceptions.""" - pass + """Common exception wrapper for template exceptions.""" + pass class DefaultFormatter(string.Formatter): @@ -37,6 +37,7 @@ class DefaultFormatter(string.Formatter): """ def __init__(self, default=''): self.default = default + def get_value(self, key, args, dict): if isinstance(key, str): return dict.get(key, self.default) @@ -49,214 +50,214 @@ def set_name_and_truncate(primary, secondary, maxlength=62): def AddDiskResourcesIfNeeded(context): - """Checks context if disk resources need to be added.""" - if default.DISK_RESOURCES in context.properties: - return context.properties[default.DISK_RESOURCES] - else: - return [] + """Checks context if disk resources need to be added.""" + if default.DISK_RESOURCES in context.properties: + return context.properties[default.DISK_RESOURCES] + else: + return [] def AutoName(base, resource, *args): - """Helper method to generate names automatically based on default.""" - auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) - if not RFC1035_RE.match(auto_name): - raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % - (auto_name, resource, RFC1035_RE.pattern)) - return auto_name + """Helper method to generate names automatically based on default.""" + auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) + if not RFC1035_RE.match(auto_name): + raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % + (auto_name, resource, RFC1035_RE.pattern)) + return auto_name def AutoRef(base, resource, *args): - """Helper method that builds a reference for an auto-named resource.""" - return Ref(AutoName(base, resource, *args)) + """Helper method that builds a reference for an auto-named resource.""" + return Ref(AutoName(base, resource, *args)) def OrderedItems(dict_obj): - """Convenient method to yield sorted iteritems of a dictionary.""" - keys = list(dict_obj.keys()) - keys.sort() - for k in keys: - yield (k, dict_obj[k]) + """Convenient method to yield sorted iteritems of a dictionary.""" + keys = list(dict_obj.keys()) + keys.sort() + for k in keys: + yield (k, dict_obj[k]) def ShortenZoneName(zone): - """Given a string that looks like a zone name, creates a shorter version.""" - geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] - geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] - coord = default.LOC[coord.lower()] - number = str(number) - letter = letter.lower() - return geo + '-' + coord + number + letter + """Given a string that looks like a zone name, creates a shorter version.""" + geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] + geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] + coord = default.LOC[coord.lower()] + number = str(number) + letter = letter.lower() + return geo + '-' + coord + number + letter def ZoneToRegion(zone): - """Derives the region from a zone name.""" - parts = zone.split('-') - if len(parts) != 3: - raise Error('Cannot derive region from zone "%s"' % zone) - return '-'.join(parts[:2]) + """Derives the region from a zone name.""" + parts = zone.split('-') + if len(parts) != 3: + raise Error('Cannot derive region from zone "%s"' % zone) + return '-'.join(parts[:2]) def FormatException(message): - """Adds more information to the exception.""" - message = ('Exception Type: %s\n' - 'Details: %s\n' - 'Message: %s\n') % (sys.exc_info()[0], - traceback.format_exc(), message) - return message + """Adds more information to the exception.""" + message = ('Exception Type: %s\n Details: %s\n' + 'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message) + return message def Ref(name): - return '$(ref.%s.selfLink)' % name + return '$(ref.%s.selfLink)' % name def RefGroup(name): - return '$(ref.%s.instanceGroup)' % name + return '$(ref.%s.instanceGroup)' % name def GlobalComputeLink(project, collection, name): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - collection, '/', name]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + collection, '/', name]) + def GlobalNetworkLink(project, network): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - default.NETWORKS, '/', network]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + default.NETWORKS, '/', network]) def LocalComputeLink(project, zone, key, value): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', - zone, '/', key, '/', value]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', + zone, '/', key, '/', value]) def ReadContext(context, prop_key): - return (context.env['project'], context.properties.get('zone', None), - context.properties[prop_key]) + return (context.env['project'], context.properties.get('zone', None), + context.properties[prop_key]) def MakeLocalComputeLink(context, key, zone=None): - if not zone: - project, zone, value = ReadContext(context, key) - else: - project, _, value = ReadContext(context, key) + if not zone: + project, zone, value = ReadContext(context, key) + else: + project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return LocalComputeLink(project, zone, key + 's', value) + if IsComputeLink(value): + return value + else: + return LocalComputeLink(project, zone, key + 's', value) def MakeGlobalComputeLink(context, key): - project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return GlobalComputeLink(project, key + 's', value) + project, _, value = ReadContext(context, key) + if IsComputeLink(value): + return value + else: + return GlobalComputeLink(project, key + 's', value) + def MakeRegionalSubnetworkLink(project, zone, subnet): - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', subnet]) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', subnet]) def MakeSubnetworkComputeLink(context, key): - project, zone, value = ReadContext(context, key) - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', value]) + project, zone, value = ReadContext(context, key) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', value]) def MakeFQHN(context, name): - return '%s.c.%s.internal' % (name, context.env['project']) + return '%s.c.%s.internal' % (name, context.env['project']) # TODO(victorg): Consider moving this method to a different file def MakeC2DImageLink(name, dev_mode=False): - if IsGlobalProjectShortcut(name) or name.startswith('http'): - return name - else: - if dev_mode: - return 'global/images/%s' % name + if IsGlobalProjectShortcut(name) or name.startswith('http'): + return name else: - return GlobalComputeLink(default.C2D_IMAGES, 'images', name) + if dev_mode: + return 'global/images/%s' % name + else: + return GlobalComputeLink(default.C2D_IMAGES, 'images', name) def IsGlobalProjectShortcut(name): - return name.startswith('projects/') or name.startswith('global/') + return name.startswith('projects/') or name.startswith('global/') def IsComputeLink(name): - return (name.startswith(default.COMPUTE_URL_BASE) or - name.startswith(default.REFERENCE_PREFIX)) + return (name.startswith(default.COMPUTE_URL_BASE) or + name.startswith(default.REFERENCE_PREFIX)) def GetNamesAndTypes(resources_dict): - return [(d['name'], d['type']) for d in resources_dict] + return [(d['name'], d['type']) for d in resources_dict] def SummarizeResources(res_dict): - """Summarizes the name of resources per resource type.""" - result = {} - for res in res_dict: - result.setdefault(res['type'], []).append(res['name']) - return result + """Summarizes the name of resources per resource type.""" + result = {} + for res in res_dict: + result.setdefault(res['type'], []).append(res['name']) + return result def ListPropertyValuesOfType(res_dict, prop, res_type): - """Lists all the values for a property of a certain type.""" - return [r['properties'][prop] for r in res_dict if r['type'] == res_type] + """Lists all the values for a property of a certain type.""" + return [r['properties'][prop] for r in res_dict if r['type'] == res_type] def MakeResource(resource_list, output_list=None): - """Wrapper for a DM template basic spec.""" - content = {'resources': resource_list} - if output_list: - content['outputs'] = output_list - return yaml.dump(content) + """Wrapper for a DM template basic spec.""" + content = {'resources': resource_list} + if output_list: + content['outputs'] = output_list + return yaml.dump(content) def TakeZoneOut(properties): - """Given a properties dictionary, removes the zone specific information.""" - - def _CleanZoneUrl(value): - value = value.split('/')[-1] if IsComputeLink(value) else value - return value - - for name in default.VM_ZONE_PROPERTIES: - if name in properties: - properties[name] = _CleanZoneUrl(properties[name]) - if default.ZONE in properties: - properties.pop(default.ZONE) - if default.BOOTDISK in properties: - properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) - if default.DISKS in properties: - for disk in properties[default.DISKS]: - # Don't touch references to other disks - if default.DISK_SOURCE in disk: - continue - if default.INITIALIZEP in disk: - disk_init = disk[default.INITIALIZEP] - if default.DISKTYPE in disk_init: - disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) + """Given a properties dictionary, removes the zone specific information.""" + + def _CleanZoneUrl(value): + value = value.split('/')[-1] if IsComputeLink(value) else value + return value + + for name in default.VM_ZONE_PROPERTIES: + if name in properties: + properties[name] = _CleanZoneUrl(properties[name]) + if default.ZONE in properties: + properties.pop(default.ZONE) + if default.BOOTDISK in properties: + properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) + if default.DISKS in properties: + for disk in properties[default.DISKS]: + # Don't touch references to other disks + if default.DISK_SOURCE in disk: + continue + if default.INITIALIZEP in disk: + disk_init = disk[default.INITIALIZEP] + if default.DISKTYPE in disk_init: + disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) def GenerateEmbeddableYaml(yaml_string): - # Because YAML is a space delimited format, we need to be careful about - # embedding one YAML document in another. This function takes in a string in - # YAML format and produces an equivalent YAML representation that can be - # inserted into arbitrary points of another YAML document. It does so by - # printing the YAML string in a single line format. Consistent ordering of - # the string is also guaranteed by using yaml.dump. - yaml_object = yaml.load(yaml_string) - dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) - return dumped_yaml + # Because YAML is a space delimited format, we need to be careful about + # embedding one YAML document in another. This function takes in a string in + # YAML format and produces an equivalent YAML representation that can be + # inserted into arbitrary points of another YAML document. It does so by + # printing the YAML string in a single line format. Consistent ordering of + # the string is also guaranteed by using yaml.dump. + yaml_object = yaml.load(yaml_string) + dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) + return dumped_yaml def FormatErrorsDec(func): - """Decorator to format exceptions if they get raised.""" + """Decorator to format exceptions if they get raised.""" - def FormatErrorsWrap(context): - try: - return func(context) - except Exception as e: - raise Error(FormatException(e.message)) + def FormatErrorsWrap(context): + try: + return func(context) + except Exception as e: + raise Error(FormatException(e.message)) - return FormatErrorsWrap + return FormatErrorsWrap diff --git a/gcp/deployment-packages/autoscale-payg/default.py b/gcp/deployment-packages/autoscale-payg/default.py index 0c7dd919..054d9e52 100755 --- a/gcp/deployment-packages/autoscale-payg/default.py +++ b/gcp/deployment-packages/autoscale-payg/default.py @@ -11,7 +11,7 @@ # 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. -"""Convenience module to hold default constants for C2D components. +"""Convinence module to hold default constants for C2D components. There should not be any logic in this module. Its purpose is to simplify analysis of commonly used GCP and properties names and identify the names @@ -23,7 +23,7 @@ # URL constants COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' -# Deployment Manager constructs +# Deploymen Manager constructs REFERENCE_PREFIX = '$(ref.' # Commonly used in properties namespace @@ -105,8 +105,8 @@ REGION_IGM = 'compute.v1.regionInstanceGroupManager' REGION_AUTOSCALER = 'compute.v1.regionAutoscaler' URL_MAP = 'compute.v1.urlMap' -VPC='compute.v1.network' -VPC_SUBNET='compute.v1.subnetwork' +VPC = 'compute.v1.network' +VPC_SUBNET = 'compute.v1.subnetwork' # Also Known As constants AKA = { diff --git a/gcp/deployment-packages/autoscale-payg/images.py b/gcp/deployment-packages/autoscale-payg/images.py index 34855e97..a452b68e 100755 --- a/gcp/deployment-packages/autoscale-payg/images.py +++ b/gcp/deployment-packages/autoscale-payg/images.py @@ -1,34 +1,34 @@ IMAGES = { - "check-point-r8120-payg": "check-point-r8120-payg-631-991001383-v20230907", - "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001383-v20230907", - "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001383-v20230907", - "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001383-v20230907", - "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001383-v20230907", - "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001383-v20230907", - "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001383-v20230907", - "check-point-r8120-byol": "check-point-r8120-byol-631-991001383-v20230907", - "check-point-r8110-payg": "check-point-r8110-payg-335-991001383-v20230907", - "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001383-v20230907", - "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001383-v20230907", - "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001383-v20230907", - "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001383-v20230907", - "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001383-v20230907", - "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001383-v20230907", - "check-point-r8110-byol": "check-point-r8110-byol-335-991001383-v20230907", - "check-point-r81-payg": "check-point-r81-payg-392-991001383-v20230907", - "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001383-v20230907", - "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001383-v20230907", - "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001383-v20230907", - "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001383-v20230907", - "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001383-v20230907", - "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001383-v20230907", - "check-point-r81-byol": "check-point-r81-byol-392-991001383-v20230907", - "check-point-r8040-payg": "check-point-r8040-payg-294-991001383-v20230907", - "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001383-v20230907", - "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001383-v20230907", - "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001383-v20230907", - "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001383-v20230907", - "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001383-v20230907", - "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001383-v20230907", - "check-point-r8040-byol": "check-point-r8040-byol-294-991001383-v20230907" -} + "check-point-r8120-payg": "check-point-r8120-payg-631-991001475-v20231221", + "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001475-v20231221", + "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", + "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", + "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001475-v20231221", + "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", + "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", + "check-point-r8120-byol": "check-point-r8120-byol-631-991001475-v20231221", + "check-point-r8110-payg": "check-point-r8110-payg-335-991001475-v20231221", + "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001475-v20231221", + "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001475-v20231221", + "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001475-v20231221", + "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001475-v20231221", + "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001475-v20231221", + "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001475-v20231221", + "check-point-r8110-byol": "check-point-r8110-byol-335-991001475-v20231221", + "check-point-r81-payg": "check-point-r81-payg-392-991001475-v20231221", + "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001475-v20231221", + "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001475-v20231221", + "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001475-v20231221", + "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001475-v20231221", + "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001475-v20231221", + "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001475-v20231221", + "check-point-r81-byol": "check-point-r81-byol-392-991001475-v20231221", + "check-point-r8040-payg": "check-point-r8040-payg-294-991001475-v20231221", + "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001475-v20231221", + "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001475-v20231221", + "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001475-v20231221", + "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001475-v20231221", + "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001475-v20231221", + "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001475-v20231221", + "check-point-r8040-byol": "check-point-r8040-byol-294-991001475-v20231221" +} \ No newline at end of file diff --git a/gcp/deployment-packages/autoscale-payg/password.py b/gcp/deployment-packages/autoscale-payg/password.py index 273210a6..bfe40f5c 100755 --- a/gcp/deployment-packages/autoscale-payg/password.py +++ b/gcp/deployment-packages/autoscale-payg/password.py @@ -63,73 +63,71 @@ class InputError(Exception): - """Raised when input properties are unexpected.""" + """Raised when input properties are unexpected.""" def GenerateConfig(context): - """Entry function to generate the DM config.""" - props = context.properties - length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) - include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) + """Entry function to generate the DM config.""" + props = context.properties + length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) + include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) - if not isinstance(include_symbols, bool): - raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) + if not isinstance(include_symbols, bool): + raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) - content = { + content = { 'resources': [], 'outputs': [{ 'name': 'password', 'value': GeneratePassword(length, include_symbols) }] - } - return yaml.dump(content) + } + return yaml.dump(content) def GeneratePassword(length=8, include_symbols=False): - """Generates a random password.""" - if length < MIN_LENGTH: - raise InputError('Password length must be at least %d' % MIN_LENGTH) - - candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols - else CANDIDATES_WITHOUT_SYMBOLS) - categories = (CATEGORIES_WITH_SYMBOLS if include_symbols - else CATEGORIES_WITHOUT_SYMBOLS) - - # Generates up to the specified length minus the number of categories. - # Then inserts one character for each category, ensuring that the character - # satisfy the category if the generated string hasn't already. - generated = ([random.choice(ALPHABET)] + - [random.choice(candidates) - for _ in range(length - 1 - len(categories))]) - for category in categories: - _InsertAndEnsureSatisfaction(generated, category, candidates) - return ''.join(generated) + """Generates a random password.""" + if length < MIN_LENGTH: + raise InputError('Password length must be at least %d' % MIN_LENGTH) + + candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols + else CANDIDATES_WITHOUT_SYMBOLS) + categories = (CATEGORIES_WITH_SYMBOLS if include_symbols + else CATEGORIES_WITHOUT_SYMBOLS) + + # Generates up to the specified length minus the number of categories. + # Then inserts one character for each category, ensuring that the character + # satisfy the category if the generated string hasn't already. + generated = ([random.choice(ALPHABET)] + [random.choice(candidates) + for _ in range(length - 1 - len(categories))]) + for category in categories: + _InsertAndEnsureSatisfaction(generated, category, candidates) + return ''.join(generated) def _InsertAndEnsureSatisfaction(generated, required, all_candidates): - """Inserts 1 char into generated, satisfying required if not already. - - If the required characters are not already in the generated string, one will - be inserted. If any required character is already in the generated string, a - random character from all_candidates will be inserted. The insertion happens - at a random location but not at the beginning. - - Args: - generated: the string to be modified. - required: list of required characters to check for. - all_candidates: list of characters to choose from if the required characters - are already satisfied. - """ - if set(generated).isdisjoint(required): - # Not yet satisfied. Insert a required candidate. - _InsertInto(generated, required) - else: - # Already satisfied. Insert any candidate. - _InsertInto(generated, all_candidates) + """Inserts 1 char into generated, satisfying required if not already. + + If the required characters are not already in the generated string, one will + be inserted. If any required character is already in the generated string, a + random character from all_candidates will be inserted. The insertion happens + at a random location but not at the beginning. + + Args: + generated: the string to be modified. + required: list of required characters to check for. + all_candidates: list of characters to choose from if the required characters + are already satisfied. + """ + if set(generated).isdisjoint(required): + # Not yet satisfied. Insert a required candidate. + _InsertInto(generated, required) + else: + # Already satisfied. Insert any candidate. + _InsertInto(generated, all_candidates) def _InsertInto(generated, candidates): - """Inserts a random candidate into a random non-zero index of generated.""" - # Avoids inserting at index 0, since the first character follows its own rule. - generated.insert(random.randint(1, len(generated) - 1), - random.choice(candidates)) + """Inserts a random candidate into a random non-zero index of generated.""" + # Avoids inserting at index 0, since the first character follows its own rule. + generated.insert(random.randint(1, len(generated) - 1), random.choice(candidates)) diff --git a/gcp/deployment-packages/ha-byol/c2d_deployment_configuration.json b/gcp/deployment-packages/ha-byol/c2d_deployment_configuration.json index 834dd3f4..5af767bf 100755 --- a/gcp/deployment-packages/ha-byol/c2d_deployment_configuration.json +++ b/gcp/deployment-packages/ha-byol/c2d_deployment_configuration.json @@ -1,6 +1,6 @@ { "defaultDeploymentType": "MULTI_VM", - "imageName": "check-point-r8110-gw-byol-cluster-335-991001221-v20221221", + "imageName": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", "projectId": "checkpoint-public", "templateName": "nonexistent_template", "useSolutionPackage": "true" diff --git a/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py b/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py index 1c145dbc..3353fedd 100755 --- a/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py +++ b/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py @@ -23,7 +23,7 @@ } TEMPLATE_NAME = 'cluster' -TEMPLATE_VERSION = '20230319' +TEMPLATE_VERSION = '20231221' CLUSTER_NET_FIELD = 'cluster-network' MGMT_NET_FIELD = 'mgmt-network' @@ -34,7 +34,7 @@ startup_script = ''' #cloud-config runcmd: - - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\""' + - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\"" "osVersion=\\"{osVersion}\\"" "MaintenanceModePassword=\\"{maintenanceMode}\\""' ''' @@ -51,6 +51,7 @@ def make_gw(context, name, zone, nics, passwd=None, depends_on=None, context.properties['smart1CloudToken'] = smart1cloudToken context.properties['name'] = name context.properties['zoneConfig'] = zone + context.properties['osVersion'] = cg_version.replace(".", "") gw = { 'type': default.INSTANCE, @@ -359,7 +360,7 @@ def validate_same_region(zone_a, zone_b): def validate_both_tokens(token_a, token_b): if (not token_a and token_b) or (not token_b and token_a) or \ - (token_a and token_a == token_b): + (token_a and token_a == token_b): raise common.Error('To connect to Smart-1 Cloud, \ you must provide two tokens (one per member)') diff --git a/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py.schema b/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py.schema index 262f6b52..14607e0c 100755 --- a/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py.schema +++ b/gcp/deployment-packages/ha-byol/check-point-cluster--byol.py.schema @@ -48,7 +48,7 @@ properties: default: '' smart1CloudTokenB: type: string - default: '' + default: '' diskType: type: string default: pd-ssd @@ -66,7 +66,7 @@ properties: diskTypeProperty: diskType ha_version: type: string - default: R81.10 Cluster + default: R81.20 Cluster enum: - R80.40 Cluster - R81 Cluster @@ -86,6 +86,10 @@ properties: generatePassword: type: boolean default: False + maintenanceMode: + type: string + pattern: ^([a-z0-9A-Z.]{12,300}|)$ + default: '' allowUploadDownload: type: boolean default: False diff --git a/gcp/deployment-packages/ha-byol/common.py b/gcp/deployment-packages/ha-byol/common.py index e123c502..0a40d315 100755 --- a/gcp/deployment-packages/ha-byol/common.py +++ b/gcp/deployment-packages/ha-byol/common.py @@ -11,7 +11,7 @@ # 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. -"""Generic simple functions used for python based template generation.""" +"""Generic simple functions used for python based templage generation.""" import re import sys @@ -25,8 +25,8 @@ class Error(Exception): - """Common exception wrapper for template exceptions.""" - pass + """Common exception wrapper for template exceptions.""" + pass class DefaultFormatter(string.Formatter): @@ -37,6 +37,7 @@ class DefaultFormatter(string.Formatter): """ def __init__(self, default=''): self.default = default + def get_value(self, key, args, dict): if isinstance(key, str): return dict.get(key, self.default) @@ -49,214 +50,214 @@ def set_name_and_truncate(primary, secondary, maxlength=62): def AddDiskResourcesIfNeeded(context): - """Checks context if disk resources need to be added.""" - if default.DISK_RESOURCES in context.properties: - return context.properties[default.DISK_RESOURCES] - else: - return [] + """Checks context if disk resources need to be added.""" + if default.DISK_RESOURCES in context.properties: + return context.properties[default.DISK_RESOURCES] + else: + return [] def AutoName(base, resource, *args): - """Helper method to generate names automatically based on default.""" - auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) - if not RFC1035_RE.match(auto_name): - raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % - (auto_name, resource, RFC1035_RE.pattern)) - return auto_name + """Helper method to generate names automatically based on default.""" + auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) + if not RFC1035_RE.match(auto_name): + raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % + (auto_name, resource, RFC1035_RE.pattern)) + return auto_name def AutoRef(base, resource, *args): - """Helper method that builds a reference for an auto-named resource.""" - return Ref(AutoName(base, resource, *args)) + """Helper method that builds a reference for an auto-named resource.""" + return Ref(AutoName(base, resource, *args)) def OrderedItems(dict_obj): - """Convenient method to yield sorted iteritems of a dictionary.""" - keys = list(dict_obj.keys()) - keys.sort() - for k in keys: - yield (k, dict_obj[k]) + """Convenient method to yield sorted iteritems of a dictionary.""" + keys = list(dict_obj.keys()) + keys.sort() + for k in keys: + yield (k, dict_obj[k]) def ShortenZoneName(zone): - """Given a string that looks like a zone name, creates a shorter version.""" - geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] - geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] - coord = default.LOC[coord.lower()] - number = str(number) - letter = letter.lower() - return geo + '-' + coord + number + letter + """Given a string that looks like a zone name, creates a shorter version.""" + geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] + geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] + coord = default.LOC[coord.lower()] + number = str(number) + letter = letter.lower() + return geo + '-' + coord + number + letter def ZoneToRegion(zone): - """Derives the region from a zone name.""" - parts = zone.split('-') - if len(parts) != 3: - raise Error('Cannot derive region from zone "%s"' % zone) - return '-'.join(parts[:2]) + """Derives the region from a zone name.""" + parts = zone.split('-') + if len(parts) != 3: + raise Error('Cannot derive region from zone "%s"' % zone) + return '-'.join(parts[:2]) def FormatException(message): - """Adds more information to the exception.""" - message = ('Exception Type: %s\n' - 'Details: %s\n' - 'Message: %s\n') % (sys.exc_info()[0], - traceback.format_exc(), message) - return message + """Adds more information to the exception.""" + message = ('Exception Type: %s\n Details: %s\n' + 'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message) + return message def Ref(name): - return '$(ref.%s.selfLink)' % name + return '$(ref.%s.selfLink)' % name def RefGroup(name): - return '$(ref.%s.instanceGroup)' % name + return '$(ref.%s.instanceGroup)' % name def GlobalComputeLink(project, collection, name): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - collection, '/', name]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + collection, '/', name]) + def GlobalNetworkLink(project, network): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - default.NETWORKS, '/', network]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + default.NETWORKS, '/', network]) def LocalComputeLink(project, zone, key, value): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', - zone, '/', key, '/', value]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', + zone, '/', key, '/', value]) def ReadContext(context, prop_key): - return (context.env['project'], context.properties.get('zone', None), - context.properties[prop_key]) + return (context.env['project'], context.properties.get('zone', None), + context.properties[prop_key]) def MakeLocalComputeLink(context, key, zone=None): - if not zone: - project, zone, value = ReadContext(context, key) - else: - project, _, value = ReadContext(context, key) + if not zone: + project, zone, value = ReadContext(context, key) + else: + project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return LocalComputeLink(project, zone, key + 's', value) + if IsComputeLink(value): + return value + else: + return LocalComputeLink(project, zone, key + 's', value) def MakeGlobalComputeLink(context, key): - project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return GlobalComputeLink(project, key + 's', value) + project, _, value = ReadContext(context, key) + if IsComputeLink(value): + return value + else: + return GlobalComputeLink(project, key + 's', value) + def MakeRegionalSubnetworkLink(project, zone, subnet): - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', subnet]) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', subnet]) def MakeSubnetworkComputeLink(context, key): - project, zone, value = ReadContext(context, key) - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', value]) + project, zone, value = ReadContext(context, key) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', value]) def MakeFQHN(context, name): - return '%s.c.%s.internal' % (name, context.env['project']) + return '%s.c.%s.internal' % (name, context.env['project']) # TODO(victorg): Consider moving this method to a different file def MakeC2DImageLink(name, dev_mode=False): - if IsGlobalProjectShortcut(name) or name.startswith('http'): - return name - else: - if dev_mode: - return 'global/images/%s' % name + if IsGlobalProjectShortcut(name) or name.startswith('http'): + return name else: - return GlobalComputeLink(default.C2D_IMAGES, 'images', name) + if dev_mode: + return 'global/images/%s' % name + else: + return GlobalComputeLink(default.C2D_IMAGES, 'images', name) def IsGlobalProjectShortcut(name): - return name.startswith('projects/') or name.startswith('global/') + return name.startswith('projects/') or name.startswith('global/') def IsComputeLink(name): - return (name.startswith(default.COMPUTE_URL_BASE) or - name.startswith(default.REFERENCE_PREFIX)) + return (name.startswith(default.COMPUTE_URL_BASE) or + name.startswith(default.REFERENCE_PREFIX)) def GetNamesAndTypes(resources_dict): - return [(d['name'], d['type']) for d in resources_dict] + return [(d['name'], d['type']) for d in resources_dict] def SummarizeResources(res_dict): - """Summarizes the name of resources per resource type.""" - result = {} - for res in res_dict: - result.setdefault(res['type'], []).append(res['name']) - return result + """Summarizes the name of resources per resource type.""" + result = {} + for res in res_dict: + result.setdefault(res['type'], []).append(res['name']) + return result def ListPropertyValuesOfType(res_dict, prop, res_type): - """Lists all the values for a property of a certain type.""" - return [r['properties'][prop] for r in res_dict if r['type'] == res_type] + """Lists all the values for a property of a certain type.""" + return [r['properties'][prop] for r in res_dict if r['type'] == res_type] def MakeResource(resource_list, output_list=None): - """Wrapper for a DM template basic spec.""" - content = {'resources': resource_list} - if output_list: - content['outputs'] = output_list - return yaml.dump(content) + """Wrapper for a DM template basic spec.""" + content = {'resources': resource_list} + if output_list: + content['outputs'] = output_list + return yaml.dump(content) def TakeZoneOut(properties): - """Given a properties dictionary, removes the zone specific information.""" - - def _CleanZoneUrl(value): - value = value.split('/')[-1] if IsComputeLink(value) else value - return value - - for name in default.VM_ZONE_PROPERTIES: - if name in properties: - properties[name] = _CleanZoneUrl(properties[name]) - if default.ZONE in properties: - properties.pop(default.ZONE) - if default.BOOTDISK in properties: - properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) - if default.DISKS in properties: - for disk in properties[default.DISKS]: - # Don't touch references to other disks - if default.DISK_SOURCE in disk: - continue - if default.INITIALIZEP in disk: - disk_init = disk[default.INITIALIZEP] - if default.DISKTYPE in disk_init: - disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) + """Given a properties dictionary, removes the zone specific information.""" + + def _CleanZoneUrl(value): + value = value.split('/')[-1] if IsComputeLink(value) else value + return value + + for name in default.VM_ZONE_PROPERTIES: + if name in properties: + properties[name] = _CleanZoneUrl(properties[name]) + if default.ZONE in properties: + properties.pop(default.ZONE) + if default.BOOTDISK in properties: + properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) + if default.DISKS in properties: + for disk in properties[default.DISKS]: + # Don't touch references to other disks + if default.DISK_SOURCE in disk: + continue + if default.INITIALIZEP in disk: + disk_init = disk[default.INITIALIZEP] + if default.DISKTYPE in disk_init: + disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) def GenerateEmbeddableYaml(yaml_string): - # Because YAML is a space delimited format, we need to be careful about - # embedding one YAML document in another. This function takes in a string in - # YAML format and produces an equivalent YAML representation that can be - # inserted into arbitrary points of another YAML document. It does so by - # printing the YAML string in a single line format. Consistent ordering of - # the string is also guaranteed by using yaml.dump. - yaml_object = yaml.load(yaml_string) - dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) - return dumped_yaml + # Because YAML is a space delimited format, we need to be careful about + # embedding one YAML document in another. This function takes in a string in + # YAML format and produces an equivalent YAML representation that can be + # inserted into arbitrary points of another YAML document. It does so by + # printing the YAML string in a single line format. Consistent ordering of + # the string is also guaranteed by using yaml.dump. + yaml_object = yaml.load(yaml_string) + dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) + return dumped_yaml def FormatErrorsDec(func): - """Decorator to format exceptions if they get raised.""" + """Decorator to format exceptions if they get raised.""" - def FormatErrorsWrap(context): - try: - return func(context) - except Exception as e: - raise Error(FormatException(e.message)) + def FormatErrorsWrap(context): + try: + return func(context) + except Exception as e: + raise Error(FormatException(e.message)) - return FormatErrorsWrap + return FormatErrorsWrap diff --git a/gcp/deployment-packages/ha-byol/default.py b/gcp/deployment-packages/ha-byol/default.py index 0c7dd919..054d9e52 100755 --- a/gcp/deployment-packages/ha-byol/default.py +++ b/gcp/deployment-packages/ha-byol/default.py @@ -11,7 +11,7 @@ # 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. -"""Convenience module to hold default constants for C2D components. +"""Convinence module to hold default constants for C2D components. There should not be any logic in this module. Its purpose is to simplify analysis of commonly used GCP and properties names and identify the names @@ -23,7 +23,7 @@ # URL constants COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' -# Deployment Manager constructs +# Deploymen Manager constructs REFERENCE_PREFIX = '$(ref.' # Commonly used in properties namespace @@ -105,8 +105,8 @@ REGION_IGM = 'compute.v1.regionInstanceGroupManager' REGION_AUTOSCALER = 'compute.v1.regionAutoscaler' URL_MAP = 'compute.v1.urlMap' -VPC='compute.v1.network' -VPC_SUBNET='compute.v1.subnetwork' +VPC = 'compute.v1.network' +VPC_SUBNET = 'compute.v1.subnetwork' # Also Known As constants AKA = { diff --git a/gcp/deployment-packages/ha-byol/images.py b/gcp/deployment-packages/ha-byol/images.py index 34855e97..a452b68e 100755 --- a/gcp/deployment-packages/ha-byol/images.py +++ b/gcp/deployment-packages/ha-byol/images.py @@ -1,34 +1,34 @@ IMAGES = { - "check-point-r8120-payg": "check-point-r8120-payg-631-991001383-v20230907", - "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001383-v20230907", - "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001383-v20230907", - "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001383-v20230907", - "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001383-v20230907", - "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001383-v20230907", - "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001383-v20230907", - "check-point-r8120-byol": "check-point-r8120-byol-631-991001383-v20230907", - "check-point-r8110-payg": "check-point-r8110-payg-335-991001383-v20230907", - "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001383-v20230907", - "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001383-v20230907", - "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001383-v20230907", - "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001383-v20230907", - "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001383-v20230907", - "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001383-v20230907", - "check-point-r8110-byol": "check-point-r8110-byol-335-991001383-v20230907", - "check-point-r81-payg": "check-point-r81-payg-392-991001383-v20230907", - "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001383-v20230907", - "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001383-v20230907", - "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001383-v20230907", - "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001383-v20230907", - "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001383-v20230907", - "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001383-v20230907", - "check-point-r81-byol": "check-point-r81-byol-392-991001383-v20230907", - "check-point-r8040-payg": "check-point-r8040-payg-294-991001383-v20230907", - "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001383-v20230907", - "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001383-v20230907", - "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001383-v20230907", - "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001383-v20230907", - "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001383-v20230907", - "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001383-v20230907", - "check-point-r8040-byol": "check-point-r8040-byol-294-991001383-v20230907" -} + "check-point-r8120-payg": "check-point-r8120-payg-631-991001475-v20231221", + "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001475-v20231221", + "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", + "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", + "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001475-v20231221", + "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", + "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", + "check-point-r8120-byol": "check-point-r8120-byol-631-991001475-v20231221", + "check-point-r8110-payg": "check-point-r8110-payg-335-991001475-v20231221", + "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001475-v20231221", + "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001475-v20231221", + "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001475-v20231221", + "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001475-v20231221", + "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001475-v20231221", + "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001475-v20231221", + "check-point-r8110-byol": "check-point-r8110-byol-335-991001475-v20231221", + "check-point-r81-payg": "check-point-r81-payg-392-991001475-v20231221", + "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001475-v20231221", + "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001475-v20231221", + "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001475-v20231221", + "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001475-v20231221", + "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001475-v20231221", + "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001475-v20231221", + "check-point-r81-byol": "check-point-r81-byol-392-991001475-v20231221", + "check-point-r8040-payg": "check-point-r8040-payg-294-991001475-v20231221", + "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001475-v20231221", + "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001475-v20231221", + "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001475-v20231221", + "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001475-v20231221", + "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001475-v20231221", + "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001475-v20231221", + "check-point-r8040-byol": "check-point-r8040-byol-294-991001475-v20231221" +} \ No newline at end of file diff --git a/gcp/deployment-packages/ha-byol/password.py b/gcp/deployment-packages/ha-byol/password.py index 273210a6..bfe40f5c 100755 --- a/gcp/deployment-packages/ha-byol/password.py +++ b/gcp/deployment-packages/ha-byol/password.py @@ -63,73 +63,71 @@ class InputError(Exception): - """Raised when input properties are unexpected.""" + """Raised when input properties are unexpected.""" def GenerateConfig(context): - """Entry function to generate the DM config.""" - props = context.properties - length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) - include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) + """Entry function to generate the DM config.""" + props = context.properties + length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) + include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) - if not isinstance(include_symbols, bool): - raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) + if not isinstance(include_symbols, bool): + raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) - content = { + content = { 'resources': [], 'outputs': [{ 'name': 'password', 'value': GeneratePassword(length, include_symbols) }] - } - return yaml.dump(content) + } + return yaml.dump(content) def GeneratePassword(length=8, include_symbols=False): - """Generates a random password.""" - if length < MIN_LENGTH: - raise InputError('Password length must be at least %d' % MIN_LENGTH) - - candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols - else CANDIDATES_WITHOUT_SYMBOLS) - categories = (CATEGORIES_WITH_SYMBOLS if include_symbols - else CATEGORIES_WITHOUT_SYMBOLS) - - # Generates up to the specified length minus the number of categories. - # Then inserts one character for each category, ensuring that the character - # satisfy the category if the generated string hasn't already. - generated = ([random.choice(ALPHABET)] + - [random.choice(candidates) - for _ in range(length - 1 - len(categories))]) - for category in categories: - _InsertAndEnsureSatisfaction(generated, category, candidates) - return ''.join(generated) + """Generates a random password.""" + if length < MIN_LENGTH: + raise InputError('Password length must be at least %d' % MIN_LENGTH) + + candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols + else CANDIDATES_WITHOUT_SYMBOLS) + categories = (CATEGORIES_WITH_SYMBOLS if include_symbols + else CATEGORIES_WITHOUT_SYMBOLS) + + # Generates up to the specified length minus the number of categories. + # Then inserts one character for each category, ensuring that the character + # satisfy the category if the generated string hasn't already. + generated = ([random.choice(ALPHABET)] + [random.choice(candidates) + for _ in range(length - 1 - len(categories))]) + for category in categories: + _InsertAndEnsureSatisfaction(generated, category, candidates) + return ''.join(generated) def _InsertAndEnsureSatisfaction(generated, required, all_candidates): - """Inserts 1 char into generated, satisfying required if not already. - - If the required characters are not already in the generated string, one will - be inserted. If any required character is already in the generated string, a - random character from all_candidates will be inserted. The insertion happens - at a random location but not at the beginning. - - Args: - generated: the string to be modified. - required: list of required characters to check for. - all_candidates: list of characters to choose from if the required characters - are already satisfied. - """ - if set(generated).isdisjoint(required): - # Not yet satisfied. Insert a required candidate. - _InsertInto(generated, required) - else: - # Already satisfied. Insert any candidate. - _InsertInto(generated, all_candidates) + """Inserts 1 char into generated, satisfying required if not already. + + If the required characters are not already in the generated string, one will + be inserted. If any required character is already in the generated string, a + random character from all_candidates will be inserted. The insertion happens + at a random location but not at the beginning. + + Args: + generated: the string to be modified. + required: list of required characters to check for. + all_candidates: list of characters to choose from if the required characters + are already satisfied. + """ + if set(generated).isdisjoint(required): + # Not yet satisfied. Insert a required candidate. + _InsertInto(generated, required) + else: + # Already satisfied. Insert any candidate. + _InsertInto(generated, all_candidates) def _InsertInto(generated, candidates): - """Inserts a random candidate into a random non-zero index of generated.""" - # Avoids inserting at index 0, since the first character follows its own rule. - generated.insert(random.randint(1, len(generated) - 1), - random.choice(candidates)) + """Inserts a random candidate into a random non-zero index of generated.""" + # Avoids inserting at index 0, since the first character follows its own rule. + generated.insert(random.randint(1, len(generated) - 1), random.choice(candidates)) diff --git a/gcp/deployment-packages/ha-payg/c2d_deployment_configuration.json b/gcp/deployment-packages/ha-payg/c2d_deployment_configuration.json index 77ad27f0..81bed1f6 100755 --- a/gcp/deployment-packages/ha-payg/c2d_deployment_configuration.json +++ b/gcp/deployment-packages/ha-payg/c2d_deployment_configuration.json @@ -1,6 +1,6 @@ { "defaultDeploymentType": "MULTI_VM", - "imageName": "check-point-r8110-gw-payg-cluster-335-991001221-v20221221", + "imageName": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", "projectId": "checkpoint-public", "templateName": "nonexistent_template", "useSolutionPackage": "true" diff --git a/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py b/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py index 3e44bd26..77a7b70d 100755 --- a/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py +++ b/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py @@ -23,7 +23,7 @@ } TEMPLATE_NAME = 'cluster' -TEMPLATE_VERSION = '20230319' +TEMPLATE_VERSION = '20231221' CLUSTER_NET_FIELD = 'cluster-network' MGMT_NET_FIELD = 'mgmt-network' @@ -34,7 +34,7 @@ startup_script = ''' #cloud-config runcmd: - - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\""' + - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\"" "osVersion=\\"{osVersion}\\"" "MaintenanceModePassword=\\"{maintenanceMode}\\""' ''' @@ -51,6 +51,7 @@ def make_gw(context, name, zone, nics, passwd=None, depends_on=None, context.properties['smart1CloudToken'] = smart1cloudToken context.properties['name'] = name context.properties['zoneConfig'] = zone + context.properties['osVersion'] = cg_version.replace(".", "") gw = { 'type': default.INSTANCE, @@ -359,7 +360,7 @@ def validate_same_region(zone_a, zone_b): def validate_both_tokens(token_a, token_b): if (not token_a and token_b) or (not token_b and token_a) or \ - (token_a and token_a == token_b): + (token_a and token_a == token_b): raise common.Error('To connect to Smart-1 Cloud, \ you must provide two tokens (one per member)') diff --git a/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py.schema b/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py.schema index 28006093..a6f44c1b 100755 --- a/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py.schema +++ b/gcp/deployment-packages/ha-payg/check-point-cluster--payg.py.schema @@ -48,7 +48,7 @@ properties: default: '' smart1CloudTokenB: type: string - default: '' + default: '' diskType: type: string default: pd-ssd @@ -66,7 +66,7 @@ properties: diskTypeProperty: diskType ha_version: type: string - default: R81.10 Cluster + default: R81.20 Cluster enum: - R80.40 Cluster - R81 Cluster @@ -86,6 +86,10 @@ properties: generatePassword: type: boolean default: False + maintenanceMode: + type: string + pattern: ^([a-z0-9A-Z.]{12,300}|)$ + default: '' allowUploadDownload: type: boolean default: False diff --git a/gcp/deployment-packages/ha-payg/common.py b/gcp/deployment-packages/ha-payg/common.py index e123c502..0a40d315 100755 --- a/gcp/deployment-packages/ha-payg/common.py +++ b/gcp/deployment-packages/ha-payg/common.py @@ -11,7 +11,7 @@ # 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. -"""Generic simple functions used for python based template generation.""" +"""Generic simple functions used for python based templage generation.""" import re import sys @@ -25,8 +25,8 @@ class Error(Exception): - """Common exception wrapper for template exceptions.""" - pass + """Common exception wrapper for template exceptions.""" + pass class DefaultFormatter(string.Formatter): @@ -37,6 +37,7 @@ class DefaultFormatter(string.Formatter): """ def __init__(self, default=''): self.default = default + def get_value(self, key, args, dict): if isinstance(key, str): return dict.get(key, self.default) @@ -49,214 +50,214 @@ def set_name_and_truncate(primary, secondary, maxlength=62): def AddDiskResourcesIfNeeded(context): - """Checks context if disk resources need to be added.""" - if default.DISK_RESOURCES in context.properties: - return context.properties[default.DISK_RESOURCES] - else: - return [] + """Checks context if disk resources need to be added.""" + if default.DISK_RESOURCES in context.properties: + return context.properties[default.DISK_RESOURCES] + else: + return [] def AutoName(base, resource, *args): - """Helper method to generate names automatically based on default.""" - auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) - if not RFC1035_RE.match(auto_name): - raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % - (auto_name, resource, RFC1035_RE.pattern)) - return auto_name + """Helper method to generate names automatically based on default.""" + auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) + if not RFC1035_RE.match(auto_name): + raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % + (auto_name, resource, RFC1035_RE.pattern)) + return auto_name def AutoRef(base, resource, *args): - """Helper method that builds a reference for an auto-named resource.""" - return Ref(AutoName(base, resource, *args)) + """Helper method that builds a reference for an auto-named resource.""" + return Ref(AutoName(base, resource, *args)) def OrderedItems(dict_obj): - """Convenient method to yield sorted iteritems of a dictionary.""" - keys = list(dict_obj.keys()) - keys.sort() - for k in keys: - yield (k, dict_obj[k]) + """Convenient method to yield sorted iteritems of a dictionary.""" + keys = list(dict_obj.keys()) + keys.sort() + for k in keys: + yield (k, dict_obj[k]) def ShortenZoneName(zone): - """Given a string that looks like a zone name, creates a shorter version.""" - geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] - geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] - coord = default.LOC[coord.lower()] - number = str(number) - letter = letter.lower() - return geo + '-' + coord + number + letter + """Given a string that looks like a zone name, creates a shorter version.""" + geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] + geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] + coord = default.LOC[coord.lower()] + number = str(number) + letter = letter.lower() + return geo + '-' + coord + number + letter def ZoneToRegion(zone): - """Derives the region from a zone name.""" - parts = zone.split('-') - if len(parts) != 3: - raise Error('Cannot derive region from zone "%s"' % zone) - return '-'.join(parts[:2]) + """Derives the region from a zone name.""" + parts = zone.split('-') + if len(parts) != 3: + raise Error('Cannot derive region from zone "%s"' % zone) + return '-'.join(parts[:2]) def FormatException(message): - """Adds more information to the exception.""" - message = ('Exception Type: %s\n' - 'Details: %s\n' - 'Message: %s\n') % (sys.exc_info()[0], - traceback.format_exc(), message) - return message + """Adds more information to the exception.""" + message = ('Exception Type: %s\n Details: %s\n' + 'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message) + return message def Ref(name): - return '$(ref.%s.selfLink)' % name + return '$(ref.%s.selfLink)' % name def RefGroup(name): - return '$(ref.%s.instanceGroup)' % name + return '$(ref.%s.instanceGroup)' % name def GlobalComputeLink(project, collection, name): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - collection, '/', name]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + collection, '/', name]) + def GlobalNetworkLink(project, network): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - default.NETWORKS, '/', network]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + default.NETWORKS, '/', network]) def LocalComputeLink(project, zone, key, value): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', - zone, '/', key, '/', value]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', + zone, '/', key, '/', value]) def ReadContext(context, prop_key): - return (context.env['project'], context.properties.get('zone', None), - context.properties[prop_key]) + return (context.env['project'], context.properties.get('zone', None), + context.properties[prop_key]) def MakeLocalComputeLink(context, key, zone=None): - if not zone: - project, zone, value = ReadContext(context, key) - else: - project, _, value = ReadContext(context, key) + if not zone: + project, zone, value = ReadContext(context, key) + else: + project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return LocalComputeLink(project, zone, key + 's', value) + if IsComputeLink(value): + return value + else: + return LocalComputeLink(project, zone, key + 's', value) def MakeGlobalComputeLink(context, key): - project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return GlobalComputeLink(project, key + 's', value) + project, _, value = ReadContext(context, key) + if IsComputeLink(value): + return value + else: + return GlobalComputeLink(project, key + 's', value) + def MakeRegionalSubnetworkLink(project, zone, subnet): - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', subnet]) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', subnet]) def MakeSubnetworkComputeLink(context, key): - project, zone, value = ReadContext(context, key) - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', value]) + project, zone, value = ReadContext(context, key) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', value]) def MakeFQHN(context, name): - return '%s.c.%s.internal' % (name, context.env['project']) + return '%s.c.%s.internal' % (name, context.env['project']) # TODO(victorg): Consider moving this method to a different file def MakeC2DImageLink(name, dev_mode=False): - if IsGlobalProjectShortcut(name) or name.startswith('http'): - return name - else: - if dev_mode: - return 'global/images/%s' % name + if IsGlobalProjectShortcut(name) or name.startswith('http'): + return name else: - return GlobalComputeLink(default.C2D_IMAGES, 'images', name) + if dev_mode: + return 'global/images/%s' % name + else: + return GlobalComputeLink(default.C2D_IMAGES, 'images', name) def IsGlobalProjectShortcut(name): - return name.startswith('projects/') or name.startswith('global/') + return name.startswith('projects/') or name.startswith('global/') def IsComputeLink(name): - return (name.startswith(default.COMPUTE_URL_BASE) or - name.startswith(default.REFERENCE_PREFIX)) + return (name.startswith(default.COMPUTE_URL_BASE) or + name.startswith(default.REFERENCE_PREFIX)) def GetNamesAndTypes(resources_dict): - return [(d['name'], d['type']) for d in resources_dict] + return [(d['name'], d['type']) for d in resources_dict] def SummarizeResources(res_dict): - """Summarizes the name of resources per resource type.""" - result = {} - for res in res_dict: - result.setdefault(res['type'], []).append(res['name']) - return result + """Summarizes the name of resources per resource type.""" + result = {} + for res in res_dict: + result.setdefault(res['type'], []).append(res['name']) + return result def ListPropertyValuesOfType(res_dict, prop, res_type): - """Lists all the values for a property of a certain type.""" - return [r['properties'][prop] for r in res_dict if r['type'] == res_type] + """Lists all the values for a property of a certain type.""" + return [r['properties'][prop] for r in res_dict if r['type'] == res_type] def MakeResource(resource_list, output_list=None): - """Wrapper for a DM template basic spec.""" - content = {'resources': resource_list} - if output_list: - content['outputs'] = output_list - return yaml.dump(content) + """Wrapper for a DM template basic spec.""" + content = {'resources': resource_list} + if output_list: + content['outputs'] = output_list + return yaml.dump(content) def TakeZoneOut(properties): - """Given a properties dictionary, removes the zone specific information.""" - - def _CleanZoneUrl(value): - value = value.split('/')[-1] if IsComputeLink(value) else value - return value - - for name in default.VM_ZONE_PROPERTIES: - if name in properties: - properties[name] = _CleanZoneUrl(properties[name]) - if default.ZONE in properties: - properties.pop(default.ZONE) - if default.BOOTDISK in properties: - properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) - if default.DISKS in properties: - for disk in properties[default.DISKS]: - # Don't touch references to other disks - if default.DISK_SOURCE in disk: - continue - if default.INITIALIZEP in disk: - disk_init = disk[default.INITIALIZEP] - if default.DISKTYPE in disk_init: - disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) + """Given a properties dictionary, removes the zone specific information.""" + + def _CleanZoneUrl(value): + value = value.split('/')[-1] if IsComputeLink(value) else value + return value + + for name in default.VM_ZONE_PROPERTIES: + if name in properties: + properties[name] = _CleanZoneUrl(properties[name]) + if default.ZONE in properties: + properties.pop(default.ZONE) + if default.BOOTDISK in properties: + properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) + if default.DISKS in properties: + for disk in properties[default.DISKS]: + # Don't touch references to other disks + if default.DISK_SOURCE in disk: + continue + if default.INITIALIZEP in disk: + disk_init = disk[default.INITIALIZEP] + if default.DISKTYPE in disk_init: + disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) def GenerateEmbeddableYaml(yaml_string): - # Because YAML is a space delimited format, we need to be careful about - # embedding one YAML document in another. This function takes in a string in - # YAML format and produces an equivalent YAML representation that can be - # inserted into arbitrary points of another YAML document. It does so by - # printing the YAML string in a single line format. Consistent ordering of - # the string is also guaranteed by using yaml.dump. - yaml_object = yaml.load(yaml_string) - dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) - return dumped_yaml + # Because YAML is a space delimited format, we need to be careful about + # embedding one YAML document in another. This function takes in a string in + # YAML format and produces an equivalent YAML representation that can be + # inserted into arbitrary points of another YAML document. It does so by + # printing the YAML string in a single line format. Consistent ordering of + # the string is also guaranteed by using yaml.dump. + yaml_object = yaml.load(yaml_string) + dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) + return dumped_yaml def FormatErrorsDec(func): - """Decorator to format exceptions if they get raised.""" + """Decorator to format exceptions if they get raised.""" - def FormatErrorsWrap(context): - try: - return func(context) - except Exception as e: - raise Error(FormatException(e.message)) + def FormatErrorsWrap(context): + try: + return func(context) + except Exception as e: + raise Error(FormatException(e.message)) - return FormatErrorsWrap + return FormatErrorsWrap diff --git a/gcp/deployment-packages/ha-payg/default.py b/gcp/deployment-packages/ha-payg/default.py index 0c7dd919..054d9e52 100755 --- a/gcp/deployment-packages/ha-payg/default.py +++ b/gcp/deployment-packages/ha-payg/default.py @@ -11,7 +11,7 @@ # 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. -"""Convenience module to hold default constants for C2D components. +"""Convinence module to hold default constants for C2D components. There should not be any logic in this module. Its purpose is to simplify analysis of commonly used GCP and properties names and identify the names @@ -23,7 +23,7 @@ # URL constants COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' -# Deployment Manager constructs +# Deploymen Manager constructs REFERENCE_PREFIX = '$(ref.' # Commonly used in properties namespace @@ -105,8 +105,8 @@ REGION_IGM = 'compute.v1.regionInstanceGroupManager' REGION_AUTOSCALER = 'compute.v1.regionAutoscaler' URL_MAP = 'compute.v1.urlMap' -VPC='compute.v1.network' -VPC_SUBNET='compute.v1.subnetwork' +VPC = 'compute.v1.network' +VPC_SUBNET = 'compute.v1.subnetwork' # Also Known As constants AKA = { diff --git a/gcp/deployment-packages/ha-payg/images.py b/gcp/deployment-packages/ha-payg/images.py index 34855e97..a452b68e 100755 --- a/gcp/deployment-packages/ha-payg/images.py +++ b/gcp/deployment-packages/ha-payg/images.py @@ -1,34 +1,34 @@ IMAGES = { - "check-point-r8120-payg": "check-point-r8120-payg-631-991001383-v20230907", - "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001383-v20230907", - "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001383-v20230907", - "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001383-v20230907", - "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001383-v20230907", - "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001383-v20230907", - "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001383-v20230907", - "check-point-r8120-byol": "check-point-r8120-byol-631-991001383-v20230907", - "check-point-r8110-payg": "check-point-r8110-payg-335-991001383-v20230907", - "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001383-v20230907", - "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001383-v20230907", - "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001383-v20230907", - "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001383-v20230907", - "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001383-v20230907", - "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001383-v20230907", - "check-point-r8110-byol": "check-point-r8110-byol-335-991001383-v20230907", - "check-point-r81-payg": "check-point-r81-payg-392-991001383-v20230907", - "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001383-v20230907", - "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001383-v20230907", - "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001383-v20230907", - "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001383-v20230907", - "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001383-v20230907", - "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001383-v20230907", - "check-point-r81-byol": "check-point-r81-byol-392-991001383-v20230907", - "check-point-r8040-payg": "check-point-r8040-payg-294-991001383-v20230907", - "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001383-v20230907", - "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001383-v20230907", - "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001383-v20230907", - "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001383-v20230907", - "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001383-v20230907", - "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001383-v20230907", - "check-point-r8040-byol": "check-point-r8040-byol-294-991001383-v20230907" -} + "check-point-r8120-payg": "check-point-r8120-payg-631-991001475-v20231221", + "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001475-v20231221", + "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", + "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", + "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001475-v20231221", + "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", + "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", + "check-point-r8120-byol": "check-point-r8120-byol-631-991001475-v20231221", + "check-point-r8110-payg": "check-point-r8110-payg-335-991001475-v20231221", + "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001475-v20231221", + "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001475-v20231221", + "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001475-v20231221", + "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001475-v20231221", + "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001475-v20231221", + "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001475-v20231221", + "check-point-r8110-byol": "check-point-r8110-byol-335-991001475-v20231221", + "check-point-r81-payg": "check-point-r81-payg-392-991001475-v20231221", + "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001475-v20231221", + "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001475-v20231221", + "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001475-v20231221", + "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001475-v20231221", + "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001475-v20231221", + "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001475-v20231221", + "check-point-r81-byol": "check-point-r81-byol-392-991001475-v20231221", + "check-point-r8040-payg": "check-point-r8040-payg-294-991001475-v20231221", + "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001475-v20231221", + "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001475-v20231221", + "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001475-v20231221", + "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001475-v20231221", + "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001475-v20231221", + "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001475-v20231221", + "check-point-r8040-byol": "check-point-r8040-byol-294-991001475-v20231221" +} \ No newline at end of file diff --git a/gcp/deployment-packages/ha-payg/password.py b/gcp/deployment-packages/ha-payg/password.py index 273210a6..bfe40f5c 100755 --- a/gcp/deployment-packages/ha-payg/password.py +++ b/gcp/deployment-packages/ha-payg/password.py @@ -63,73 +63,71 @@ class InputError(Exception): - """Raised when input properties are unexpected.""" + """Raised when input properties are unexpected.""" def GenerateConfig(context): - """Entry function to generate the DM config.""" - props = context.properties - length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) - include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) + """Entry function to generate the DM config.""" + props = context.properties + length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) + include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) - if not isinstance(include_symbols, bool): - raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) + if not isinstance(include_symbols, bool): + raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) - content = { + content = { 'resources': [], 'outputs': [{ 'name': 'password', 'value': GeneratePassword(length, include_symbols) }] - } - return yaml.dump(content) + } + return yaml.dump(content) def GeneratePassword(length=8, include_symbols=False): - """Generates a random password.""" - if length < MIN_LENGTH: - raise InputError('Password length must be at least %d' % MIN_LENGTH) - - candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols - else CANDIDATES_WITHOUT_SYMBOLS) - categories = (CATEGORIES_WITH_SYMBOLS if include_symbols - else CATEGORIES_WITHOUT_SYMBOLS) - - # Generates up to the specified length minus the number of categories. - # Then inserts one character for each category, ensuring that the character - # satisfy the category if the generated string hasn't already. - generated = ([random.choice(ALPHABET)] + - [random.choice(candidates) - for _ in range(length - 1 - len(categories))]) - for category in categories: - _InsertAndEnsureSatisfaction(generated, category, candidates) - return ''.join(generated) + """Generates a random password.""" + if length < MIN_LENGTH: + raise InputError('Password length must be at least %d' % MIN_LENGTH) + + candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols + else CANDIDATES_WITHOUT_SYMBOLS) + categories = (CATEGORIES_WITH_SYMBOLS if include_symbols + else CATEGORIES_WITHOUT_SYMBOLS) + + # Generates up to the specified length minus the number of categories. + # Then inserts one character for each category, ensuring that the character + # satisfy the category if the generated string hasn't already. + generated = ([random.choice(ALPHABET)] + [random.choice(candidates) + for _ in range(length - 1 - len(categories))]) + for category in categories: + _InsertAndEnsureSatisfaction(generated, category, candidates) + return ''.join(generated) def _InsertAndEnsureSatisfaction(generated, required, all_candidates): - """Inserts 1 char into generated, satisfying required if not already. - - If the required characters are not already in the generated string, one will - be inserted. If any required character is already in the generated string, a - random character from all_candidates will be inserted. The insertion happens - at a random location but not at the beginning. - - Args: - generated: the string to be modified. - required: list of required characters to check for. - all_candidates: list of characters to choose from if the required characters - are already satisfied. - """ - if set(generated).isdisjoint(required): - # Not yet satisfied. Insert a required candidate. - _InsertInto(generated, required) - else: - # Already satisfied. Insert any candidate. - _InsertInto(generated, all_candidates) + """Inserts 1 char into generated, satisfying required if not already. + + If the required characters are not already in the generated string, one will + be inserted. If any required character is already in the generated string, a + random character from all_candidates will be inserted. The insertion happens + at a random location but not at the beginning. + + Args: + generated: the string to be modified. + required: list of required characters to check for. + all_candidates: list of characters to choose from if the required characters + are already satisfied. + """ + if set(generated).isdisjoint(required): + # Not yet satisfied. Insert a required candidate. + _InsertInto(generated, required) + else: + # Already satisfied. Insert any candidate. + _InsertInto(generated, all_candidates) def _InsertInto(generated, candidates): - """Inserts a random candidate into a random non-zero index of generated.""" - # Avoids inserting at index 0, since the first character follows its own rule. - generated.insert(random.randint(1, len(generated) - 1), - random.choice(candidates)) + """Inserts a random candidate into a random non-zero index of generated.""" + # Avoids inserting at index 0, since the first character follows its own rule. + generated.insert(random.randint(1, len(generated) - 1), random.choice(candidates)) diff --git a/gcp/deployment-packages/single-byol/c2d_deployment_configuration.json b/gcp/deployment-packages/single-byol/c2d_deployment_configuration.json index 4b9b6adc..006d39c7 100755 --- a/gcp/deployment-packages/single-byol/c2d_deployment_configuration.json +++ b/gcp/deployment-packages/single-byol/c2d_deployment_configuration.json @@ -1,6 +1,6 @@ { "defaultDeploymentType": "SINGLE_VM", - "imageName": "check-point-r8110-gw-byol-single-335-991001174-v20221113", + "imageName": "check-point-r8120-gw-byol-single-631-991001475-v20231221", "projectId": "checkpoint-public", "templateName": "nonexistent_template", "useSolutionPackage": "true" diff --git a/gcp/deployment-packages/single-byol/check-point-vsec--byol.py b/gcp/deployment-packages/single-byol/check-point-vsec--byol.py index e97d6b72..d1fd7411 100755 --- a/gcp/deployment-packages/single-byol/check-point-vsec--byol.py +++ b/gcp/deployment-packages/single-byol/check-point-vsec--byol.py @@ -28,7 +28,7 @@ MAX_NICS = 8 TEMPLATE_NAME = 'single' -TEMPLATE_VERSION = '20230319' +TEMPLATE_VERSION = '20231221' ATTRIBUTES = { 'Gateway and Management (Standalone)': { @@ -56,7 +56,7 @@ startup_script = ''' #cloud-config runcmd: - - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\""' + - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\"" "osVersion=\\"{osVersion}\\"" "MaintenanceModePassword=\\"{maintenanceMode}\\""' ''' @@ -148,6 +148,7 @@ def generate_config(context): for Gateway development.') prop['templateName'] = TEMPLATE_NAME prop['templateVersion'] = TEMPLATE_VERSION + prop['osVersion'] = prop['cloudguardVersion'].replace(".", "") prop['allowUploadDownload'] = str(prop['allowUploadDownload']).lower() if not prop['managementGUIClientNetwork'] and prop['installationType'] in { 'Gateway and Management (Standalone)', 'Management only'}: diff --git a/gcp/deployment-packages/single-byol/check-point-vsec--byol.py.schema b/gcp/deployment-packages/single-byol/check-point-vsec--byol.py.schema index e4ae47e0..f08b551a 100755 --- a/gcp/deployment-packages/single-byol/check-point-vsec--byol.py.schema +++ b/gcp/deployment-packages/single-byol/check-point-vsec--byol.py.schema @@ -144,7 +144,7 @@ properties: diskTypeProperty: diskType installationType: type: string - default: R81.10 Gateway only + default: R81.20 Gateway only enum: - R80.40 Gateway only - R80.40 Management only @@ -162,6 +162,10 @@ properties: - R81.20 Management only - R81.20 Manual Configuration - R81.20 Gateway and Management (Standalone) + maintenanceMode: + type: string + pattern: ^([a-z0-9A-Z.]{12,300}|)$ + default: '' allowUploadDownload: type: boolean default: True @@ -210,7 +214,7 @@ properties: - 7 minimum: 0 maximum: 7 - default: 0 + default: 1 additionalNetwork1: type: string x-googleProperty: diff --git a/gcp/deployment-packages/single-byol/common.py b/gcp/deployment-packages/single-byol/common.py index e123c502..0a40d315 100755 --- a/gcp/deployment-packages/single-byol/common.py +++ b/gcp/deployment-packages/single-byol/common.py @@ -11,7 +11,7 @@ # 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. -"""Generic simple functions used for python based template generation.""" +"""Generic simple functions used for python based templage generation.""" import re import sys @@ -25,8 +25,8 @@ class Error(Exception): - """Common exception wrapper for template exceptions.""" - pass + """Common exception wrapper for template exceptions.""" + pass class DefaultFormatter(string.Formatter): @@ -37,6 +37,7 @@ class DefaultFormatter(string.Formatter): """ def __init__(self, default=''): self.default = default + def get_value(self, key, args, dict): if isinstance(key, str): return dict.get(key, self.default) @@ -49,214 +50,214 @@ def set_name_and_truncate(primary, secondary, maxlength=62): def AddDiskResourcesIfNeeded(context): - """Checks context if disk resources need to be added.""" - if default.DISK_RESOURCES in context.properties: - return context.properties[default.DISK_RESOURCES] - else: - return [] + """Checks context if disk resources need to be added.""" + if default.DISK_RESOURCES in context.properties: + return context.properties[default.DISK_RESOURCES] + else: + return [] def AutoName(base, resource, *args): - """Helper method to generate names automatically based on default.""" - auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) - if not RFC1035_RE.match(auto_name): - raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % - (auto_name, resource, RFC1035_RE.pattern)) - return auto_name + """Helper method to generate names automatically based on default.""" + auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) + if not RFC1035_RE.match(auto_name): + raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % + (auto_name, resource, RFC1035_RE.pattern)) + return auto_name def AutoRef(base, resource, *args): - """Helper method that builds a reference for an auto-named resource.""" - return Ref(AutoName(base, resource, *args)) + """Helper method that builds a reference for an auto-named resource.""" + return Ref(AutoName(base, resource, *args)) def OrderedItems(dict_obj): - """Convenient method to yield sorted iteritems of a dictionary.""" - keys = list(dict_obj.keys()) - keys.sort() - for k in keys: - yield (k, dict_obj[k]) + """Convenient method to yield sorted iteritems of a dictionary.""" + keys = list(dict_obj.keys()) + keys.sort() + for k in keys: + yield (k, dict_obj[k]) def ShortenZoneName(zone): - """Given a string that looks like a zone name, creates a shorter version.""" - geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] - geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] - coord = default.LOC[coord.lower()] - number = str(number) - letter = letter.lower() - return geo + '-' + coord + number + letter + """Given a string that looks like a zone name, creates a shorter version.""" + geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] + geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] + coord = default.LOC[coord.lower()] + number = str(number) + letter = letter.lower() + return geo + '-' + coord + number + letter def ZoneToRegion(zone): - """Derives the region from a zone name.""" - parts = zone.split('-') - if len(parts) != 3: - raise Error('Cannot derive region from zone "%s"' % zone) - return '-'.join(parts[:2]) + """Derives the region from a zone name.""" + parts = zone.split('-') + if len(parts) != 3: + raise Error('Cannot derive region from zone "%s"' % zone) + return '-'.join(parts[:2]) def FormatException(message): - """Adds more information to the exception.""" - message = ('Exception Type: %s\n' - 'Details: %s\n' - 'Message: %s\n') % (sys.exc_info()[0], - traceback.format_exc(), message) - return message + """Adds more information to the exception.""" + message = ('Exception Type: %s\n Details: %s\n' + 'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message) + return message def Ref(name): - return '$(ref.%s.selfLink)' % name + return '$(ref.%s.selfLink)' % name def RefGroup(name): - return '$(ref.%s.instanceGroup)' % name + return '$(ref.%s.instanceGroup)' % name def GlobalComputeLink(project, collection, name): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - collection, '/', name]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + collection, '/', name]) + def GlobalNetworkLink(project, network): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - default.NETWORKS, '/', network]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + default.NETWORKS, '/', network]) def LocalComputeLink(project, zone, key, value): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', - zone, '/', key, '/', value]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', + zone, '/', key, '/', value]) def ReadContext(context, prop_key): - return (context.env['project'], context.properties.get('zone', None), - context.properties[prop_key]) + return (context.env['project'], context.properties.get('zone', None), + context.properties[prop_key]) def MakeLocalComputeLink(context, key, zone=None): - if not zone: - project, zone, value = ReadContext(context, key) - else: - project, _, value = ReadContext(context, key) + if not zone: + project, zone, value = ReadContext(context, key) + else: + project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return LocalComputeLink(project, zone, key + 's', value) + if IsComputeLink(value): + return value + else: + return LocalComputeLink(project, zone, key + 's', value) def MakeGlobalComputeLink(context, key): - project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return GlobalComputeLink(project, key + 's', value) + project, _, value = ReadContext(context, key) + if IsComputeLink(value): + return value + else: + return GlobalComputeLink(project, key + 's', value) + def MakeRegionalSubnetworkLink(project, zone, subnet): - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', subnet]) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', subnet]) def MakeSubnetworkComputeLink(context, key): - project, zone, value = ReadContext(context, key) - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', value]) + project, zone, value = ReadContext(context, key) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', value]) def MakeFQHN(context, name): - return '%s.c.%s.internal' % (name, context.env['project']) + return '%s.c.%s.internal' % (name, context.env['project']) # TODO(victorg): Consider moving this method to a different file def MakeC2DImageLink(name, dev_mode=False): - if IsGlobalProjectShortcut(name) or name.startswith('http'): - return name - else: - if dev_mode: - return 'global/images/%s' % name + if IsGlobalProjectShortcut(name) or name.startswith('http'): + return name else: - return GlobalComputeLink(default.C2D_IMAGES, 'images', name) + if dev_mode: + return 'global/images/%s' % name + else: + return GlobalComputeLink(default.C2D_IMAGES, 'images', name) def IsGlobalProjectShortcut(name): - return name.startswith('projects/') or name.startswith('global/') + return name.startswith('projects/') or name.startswith('global/') def IsComputeLink(name): - return (name.startswith(default.COMPUTE_URL_BASE) or - name.startswith(default.REFERENCE_PREFIX)) + return (name.startswith(default.COMPUTE_URL_BASE) or + name.startswith(default.REFERENCE_PREFIX)) def GetNamesAndTypes(resources_dict): - return [(d['name'], d['type']) for d in resources_dict] + return [(d['name'], d['type']) for d in resources_dict] def SummarizeResources(res_dict): - """Summarizes the name of resources per resource type.""" - result = {} - for res in res_dict: - result.setdefault(res['type'], []).append(res['name']) - return result + """Summarizes the name of resources per resource type.""" + result = {} + for res in res_dict: + result.setdefault(res['type'], []).append(res['name']) + return result def ListPropertyValuesOfType(res_dict, prop, res_type): - """Lists all the values for a property of a certain type.""" - return [r['properties'][prop] for r in res_dict if r['type'] == res_type] + """Lists all the values for a property of a certain type.""" + return [r['properties'][prop] for r in res_dict if r['type'] == res_type] def MakeResource(resource_list, output_list=None): - """Wrapper for a DM template basic spec.""" - content = {'resources': resource_list} - if output_list: - content['outputs'] = output_list - return yaml.dump(content) + """Wrapper for a DM template basic spec.""" + content = {'resources': resource_list} + if output_list: + content['outputs'] = output_list + return yaml.dump(content) def TakeZoneOut(properties): - """Given a properties dictionary, removes the zone specific information.""" - - def _CleanZoneUrl(value): - value = value.split('/')[-1] if IsComputeLink(value) else value - return value - - for name in default.VM_ZONE_PROPERTIES: - if name in properties: - properties[name] = _CleanZoneUrl(properties[name]) - if default.ZONE in properties: - properties.pop(default.ZONE) - if default.BOOTDISK in properties: - properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) - if default.DISKS in properties: - for disk in properties[default.DISKS]: - # Don't touch references to other disks - if default.DISK_SOURCE in disk: - continue - if default.INITIALIZEP in disk: - disk_init = disk[default.INITIALIZEP] - if default.DISKTYPE in disk_init: - disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) + """Given a properties dictionary, removes the zone specific information.""" + + def _CleanZoneUrl(value): + value = value.split('/')[-1] if IsComputeLink(value) else value + return value + + for name in default.VM_ZONE_PROPERTIES: + if name in properties: + properties[name] = _CleanZoneUrl(properties[name]) + if default.ZONE in properties: + properties.pop(default.ZONE) + if default.BOOTDISK in properties: + properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) + if default.DISKS in properties: + for disk in properties[default.DISKS]: + # Don't touch references to other disks + if default.DISK_SOURCE in disk: + continue + if default.INITIALIZEP in disk: + disk_init = disk[default.INITIALIZEP] + if default.DISKTYPE in disk_init: + disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) def GenerateEmbeddableYaml(yaml_string): - # Because YAML is a space delimited format, we need to be careful about - # embedding one YAML document in another. This function takes in a string in - # YAML format and produces an equivalent YAML representation that can be - # inserted into arbitrary points of another YAML document. It does so by - # printing the YAML string in a single line format. Consistent ordering of - # the string is also guaranteed by using yaml.dump. - yaml_object = yaml.load(yaml_string) - dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) - return dumped_yaml + # Because YAML is a space delimited format, we need to be careful about + # embedding one YAML document in another. This function takes in a string in + # YAML format and produces an equivalent YAML representation that can be + # inserted into arbitrary points of another YAML document. It does so by + # printing the YAML string in a single line format. Consistent ordering of + # the string is also guaranteed by using yaml.dump. + yaml_object = yaml.load(yaml_string) + dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) + return dumped_yaml def FormatErrorsDec(func): - """Decorator to format exceptions if they get raised.""" + """Decorator to format exceptions if they get raised.""" - def FormatErrorsWrap(context): - try: - return func(context) - except Exception as e: - raise Error(FormatException(e.message)) + def FormatErrorsWrap(context): + try: + return func(context) + except Exception as e: + raise Error(FormatException(e.message)) - return FormatErrorsWrap + return FormatErrorsWrap diff --git a/gcp/deployment-packages/single-byol/default.py b/gcp/deployment-packages/single-byol/default.py index 0c7dd919..054d9e52 100755 --- a/gcp/deployment-packages/single-byol/default.py +++ b/gcp/deployment-packages/single-byol/default.py @@ -11,7 +11,7 @@ # 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. -"""Convenience module to hold default constants for C2D components. +"""Convinence module to hold default constants for C2D components. There should not be any logic in this module. Its purpose is to simplify analysis of commonly used GCP and properties names and identify the names @@ -23,7 +23,7 @@ # URL constants COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' -# Deployment Manager constructs +# Deploymen Manager constructs REFERENCE_PREFIX = '$(ref.' # Commonly used in properties namespace @@ -105,8 +105,8 @@ REGION_IGM = 'compute.v1.regionInstanceGroupManager' REGION_AUTOSCALER = 'compute.v1.regionAutoscaler' URL_MAP = 'compute.v1.urlMap' -VPC='compute.v1.network' -VPC_SUBNET='compute.v1.subnetwork' +VPC = 'compute.v1.network' +VPC_SUBNET = 'compute.v1.subnetwork' # Also Known As constants AKA = { diff --git a/gcp/deployment-packages/single-byol/images.py b/gcp/deployment-packages/single-byol/images.py index 34855e97..a452b68e 100755 --- a/gcp/deployment-packages/single-byol/images.py +++ b/gcp/deployment-packages/single-byol/images.py @@ -1,34 +1,34 @@ IMAGES = { - "check-point-r8120-payg": "check-point-r8120-payg-631-991001383-v20230907", - "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001383-v20230907", - "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001383-v20230907", - "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001383-v20230907", - "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001383-v20230907", - "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001383-v20230907", - "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001383-v20230907", - "check-point-r8120-byol": "check-point-r8120-byol-631-991001383-v20230907", - "check-point-r8110-payg": "check-point-r8110-payg-335-991001383-v20230907", - "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001383-v20230907", - "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001383-v20230907", - "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001383-v20230907", - "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001383-v20230907", - "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001383-v20230907", - "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001383-v20230907", - "check-point-r8110-byol": "check-point-r8110-byol-335-991001383-v20230907", - "check-point-r81-payg": "check-point-r81-payg-392-991001383-v20230907", - "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001383-v20230907", - "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001383-v20230907", - "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001383-v20230907", - "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001383-v20230907", - "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001383-v20230907", - "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001383-v20230907", - "check-point-r81-byol": "check-point-r81-byol-392-991001383-v20230907", - "check-point-r8040-payg": "check-point-r8040-payg-294-991001383-v20230907", - "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001383-v20230907", - "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001383-v20230907", - "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001383-v20230907", - "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001383-v20230907", - "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001383-v20230907", - "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001383-v20230907", - "check-point-r8040-byol": "check-point-r8040-byol-294-991001383-v20230907" -} + "check-point-r8120-payg": "check-point-r8120-payg-631-991001475-v20231221", + "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001475-v20231221", + "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", + "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", + "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001475-v20231221", + "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", + "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", + "check-point-r8120-byol": "check-point-r8120-byol-631-991001475-v20231221", + "check-point-r8110-payg": "check-point-r8110-payg-335-991001475-v20231221", + "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001475-v20231221", + "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001475-v20231221", + "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001475-v20231221", + "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001475-v20231221", + "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001475-v20231221", + "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001475-v20231221", + "check-point-r8110-byol": "check-point-r8110-byol-335-991001475-v20231221", + "check-point-r81-payg": "check-point-r81-payg-392-991001475-v20231221", + "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001475-v20231221", + "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001475-v20231221", + "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001475-v20231221", + "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001475-v20231221", + "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001475-v20231221", + "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001475-v20231221", + "check-point-r81-byol": "check-point-r81-byol-392-991001475-v20231221", + "check-point-r8040-payg": "check-point-r8040-payg-294-991001475-v20231221", + "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001475-v20231221", + "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001475-v20231221", + "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001475-v20231221", + "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001475-v20231221", + "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001475-v20231221", + "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001475-v20231221", + "check-point-r8040-byol": "check-point-r8040-byol-294-991001475-v20231221" +} \ No newline at end of file diff --git a/gcp/deployment-packages/single-byol/password.py b/gcp/deployment-packages/single-byol/password.py index 273210a6..bfe40f5c 100755 --- a/gcp/deployment-packages/single-byol/password.py +++ b/gcp/deployment-packages/single-byol/password.py @@ -63,73 +63,71 @@ class InputError(Exception): - """Raised when input properties are unexpected.""" + """Raised when input properties are unexpected.""" def GenerateConfig(context): - """Entry function to generate the DM config.""" - props = context.properties - length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) - include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) + """Entry function to generate the DM config.""" + props = context.properties + length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) + include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) - if not isinstance(include_symbols, bool): - raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) + if not isinstance(include_symbols, bool): + raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) - content = { + content = { 'resources': [], 'outputs': [{ 'name': 'password', 'value': GeneratePassword(length, include_symbols) }] - } - return yaml.dump(content) + } + return yaml.dump(content) def GeneratePassword(length=8, include_symbols=False): - """Generates a random password.""" - if length < MIN_LENGTH: - raise InputError('Password length must be at least %d' % MIN_LENGTH) - - candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols - else CANDIDATES_WITHOUT_SYMBOLS) - categories = (CATEGORIES_WITH_SYMBOLS if include_symbols - else CATEGORIES_WITHOUT_SYMBOLS) - - # Generates up to the specified length minus the number of categories. - # Then inserts one character for each category, ensuring that the character - # satisfy the category if the generated string hasn't already. - generated = ([random.choice(ALPHABET)] + - [random.choice(candidates) - for _ in range(length - 1 - len(categories))]) - for category in categories: - _InsertAndEnsureSatisfaction(generated, category, candidates) - return ''.join(generated) + """Generates a random password.""" + if length < MIN_LENGTH: + raise InputError('Password length must be at least %d' % MIN_LENGTH) + + candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols + else CANDIDATES_WITHOUT_SYMBOLS) + categories = (CATEGORIES_WITH_SYMBOLS if include_symbols + else CATEGORIES_WITHOUT_SYMBOLS) + + # Generates up to the specified length minus the number of categories. + # Then inserts one character for each category, ensuring that the character + # satisfy the category if the generated string hasn't already. + generated = ([random.choice(ALPHABET)] + [random.choice(candidates) + for _ in range(length - 1 - len(categories))]) + for category in categories: + _InsertAndEnsureSatisfaction(generated, category, candidates) + return ''.join(generated) def _InsertAndEnsureSatisfaction(generated, required, all_candidates): - """Inserts 1 char into generated, satisfying required if not already. - - If the required characters are not already in the generated string, one will - be inserted. If any required character is already in the generated string, a - random character from all_candidates will be inserted. The insertion happens - at a random location but not at the beginning. - - Args: - generated: the string to be modified. - required: list of required characters to check for. - all_candidates: list of characters to choose from if the required characters - are already satisfied. - """ - if set(generated).isdisjoint(required): - # Not yet satisfied. Insert a required candidate. - _InsertInto(generated, required) - else: - # Already satisfied. Insert any candidate. - _InsertInto(generated, all_candidates) + """Inserts 1 char into generated, satisfying required if not already. + + If the required characters are not already in the generated string, one will + be inserted. If any required character is already in the generated string, a + random character from all_candidates will be inserted. The insertion happens + at a random location but not at the beginning. + + Args: + generated: the string to be modified. + required: list of required characters to check for. + all_candidates: list of characters to choose from if the required characters + are already satisfied. + """ + if set(generated).isdisjoint(required): + # Not yet satisfied. Insert a required candidate. + _InsertInto(generated, required) + else: + # Already satisfied. Insert any candidate. + _InsertInto(generated, all_candidates) def _InsertInto(generated, candidates): - """Inserts a random candidate into a random non-zero index of generated.""" - # Avoids inserting at index 0, since the first character follows its own rule. - generated.insert(random.randint(1, len(generated) - 1), - random.choice(candidates)) + """Inserts a random candidate into a random non-zero index of generated.""" + # Avoids inserting at index 0, since the first character follows its own rule. + generated.insert(random.randint(1, len(generated) - 1), random.choice(candidates)) diff --git a/gcp/deployment-packages/single-payg/c2d_deployment_configuration.json b/gcp/deployment-packages/single-payg/c2d_deployment_configuration.json index c58cfe59..e6af487e 100755 --- a/gcp/deployment-packages/single-payg/c2d_deployment_configuration.json +++ b/gcp/deployment-packages/single-payg/c2d_deployment_configuration.json @@ -1,6 +1,6 @@ { "defaultDeploymentType": "SINGLE_VM", - "imageName": "check-point-r8110-gw-payg-single-335-991001174-v20221113", + "imageName": "check-point-r8120-gw-payg-single-631-991001475-v20231221", "projectId": "checkpoint-public", "templateName": "nonexistent_template", "useSolutionPackage": "true" diff --git a/gcp/deployment-packages/single-payg/check-point-vsec--payg.py b/gcp/deployment-packages/single-payg/check-point-vsec--payg.py index 4725c37d..fb0b0fef 100755 --- a/gcp/deployment-packages/single-payg/check-point-vsec--payg.py +++ b/gcp/deployment-packages/single-payg/check-point-vsec--payg.py @@ -28,7 +28,7 @@ MAX_NICS = 8 TEMPLATE_NAME = 'single' -TEMPLATE_VERSION = '20230319' +TEMPLATE_VERSION = '20231221' ATTRIBUTES = { 'Gateway and Management (Standalone)': { @@ -36,6 +36,11 @@ 'description': 'Check Point Security Gateway and Management', 'canIpForward': True, }, + 'Management only': { + 'tags': [MANAGEMENT], + 'description': 'Check Point Security Management', + 'canIpForward': False, + }, 'Gateway only': { 'tags': [GATEWAY], 'description': 'Check Point Security Gateway', @@ -51,7 +56,7 @@ startup_script = ''' #cloud-config runcmd: - - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\""' + - 'python3 /etc/cloud_config.py "generatePassword=\\"{generatePassword}\\"" "allowUploadDownload=\\"{allowUploadDownload}\\"" "templateName=\\"{templateName}\\"" "templateVersion=\\"{templateVersion}\\"" "mgmtNIC=\\"{mgmtNIC}\\"" "hasInternet=\\"{hasInternet}\\"" "config_url=\\"{config_url}\\"" "config_path=\\"{config_path}\\"" "installationType=\\"{installationType}\\"" "enableMonitoring=\\"{enableMonitoring}\\"" "shell=\\"{shell}\\"" "computed_sic_key=\\"{computed_sic_key}\\"" "sicKey=\\"{sicKey}\\"" "managementGUIClientNetwork=\\"{managementGUIClientNetwork}\\"" "primary_cluster_address_name=\\"{primary_cluster_address_name}\\"" "secondary_cluster_address_name=\\"{secondary_cluster_address_name}\\"" "managementNetwork=\\"{managementNetwork}\\"" "numAdditionalNICs=\\"{numAdditionalNICs}\\"" "smart1CloudToken=\\"{smart1CloudToken}\\"" "name=\\"{name}\\"" "zone=\\"{zoneConfig}\\"" "region=\\"{region}\\"" "osVersion=\\"{osVersion}\\"" "MaintenanceModePassword=\\"{maintenanceMode}\\""' ''' @@ -143,9 +148,10 @@ def generate_config(context): for Gateway development.') prop['templateName'] = TEMPLATE_NAME prop['templateVersion'] = TEMPLATE_VERSION + prop['osVersion'] = prop['cloudguardVersion'].replace(".", "") prop['allowUploadDownload'] = str(prop['allowUploadDownload']).lower() if not prop['managementGUIClientNetwork'] and prop['installationType'] in { - 'Gateway and Management (Standalone)'}: + 'Gateway and Management (Standalone)', 'Management only'}: raise Exception('Allowed GUI clients are required when installing ' 'a management server') for k in ['managementGUIClientNetwork']: diff --git a/gcp/deployment-packages/single-payg/check-point-vsec--payg.py.schema b/gcp/deployment-packages/single-payg/check-point-vsec--payg.py.schema index f3288fff..8383e1c7 100755 --- a/gcp/deployment-packages/single-payg/check-point-vsec--payg.py.schema +++ b/gcp/deployment-packages/single-payg/check-point-vsec--payg.py.schema @@ -144,7 +144,7 @@ properties: diskTypeProperty: diskType installationType: type: string - default: R81.10 Gateway only + default: R81.20 Gateway only enum: - R80.40 Gateway only - R80.40 Manual Configuration @@ -158,6 +158,10 @@ properties: - R81.20 Gateway only - R81.20 Manual Configuration - R81.20 Gateway and Management (Standalone) + maintenanceMode: + type: string + pattern: ^([a-z0-9A-Z.]{12,300}|)$ + default: '' allowUploadDownload: type: boolean default: True @@ -206,7 +210,7 @@ properties: - 7 minimum: 0 maximum: 7 - default: 0 + default: 1 additionalNetwork1: type: string x-googleProperty: diff --git a/gcp/deployment-packages/single-payg/common.py b/gcp/deployment-packages/single-payg/common.py index e123c502..0a40d315 100755 --- a/gcp/deployment-packages/single-payg/common.py +++ b/gcp/deployment-packages/single-payg/common.py @@ -11,7 +11,7 @@ # 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. -"""Generic simple functions used for python based template generation.""" +"""Generic simple functions used for python based templage generation.""" import re import sys @@ -25,8 +25,8 @@ class Error(Exception): - """Common exception wrapper for template exceptions.""" - pass + """Common exception wrapper for template exceptions.""" + pass class DefaultFormatter(string.Formatter): @@ -37,6 +37,7 @@ class DefaultFormatter(string.Formatter): """ def __init__(self, default=''): self.default = default + def get_value(self, key, args, dict): if isinstance(key, str): return dict.get(key, self.default) @@ -49,214 +50,214 @@ def set_name_and_truncate(primary, secondary, maxlength=62): def AddDiskResourcesIfNeeded(context): - """Checks context if disk resources need to be added.""" - if default.DISK_RESOURCES in context.properties: - return context.properties[default.DISK_RESOURCES] - else: - return [] + """Checks context if disk resources need to be added.""" + if default.DISK_RESOURCES in context.properties: + return context.properties[default.DISK_RESOURCES] + else: + return [] def AutoName(base, resource, *args): - """Helper method to generate names automatically based on default.""" - auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) - if not RFC1035_RE.match(auto_name): - raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % - (auto_name, resource, RFC1035_RE.pattern)) - return auto_name + """Helper method to generate names automatically based on default.""" + auto_name = '%s-%s' % (base, '-'.join(list(args) + [default.AKA[resource]])) + if not RFC1035_RE.match(auto_name): + raise Error('"%s" name for type %s does not match RFC1035 regex (%s)' % + (auto_name, resource, RFC1035_RE.pattern)) + return auto_name def AutoRef(base, resource, *args): - """Helper method that builds a reference for an auto-named resource.""" - return Ref(AutoName(base, resource, *args)) + """Helper method that builds a reference for an auto-named resource.""" + return Ref(AutoName(base, resource, *args)) def OrderedItems(dict_obj): - """Convenient method to yield sorted iteritems of a dictionary.""" - keys = list(dict_obj.keys()) - keys.sort() - for k in keys: - yield (k, dict_obj[k]) + """Convenient method to yield sorted iteritems of a dictionary.""" + keys = list(dict_obj.keys()) + keys.sort() + for k in keys: + yield (k, dict_obj[k]) def ShortenZoneName(zone): - """Given a string that looks like a zone name, creates a shorter version.""" - geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] - geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] - coord = default.LOC[coord.lower()] - number = str(number) - letter = letter.lower() - return geo + '-' + coord + number + letter + """Given a string that looks like a zone name, creates a shorter version.""" + geo, coord, number, letter = re.findall(r'(\w+)-(\w+)(\d)-(\w)', zone)[0] + geo = geo.lower() if len(geo) == 2 else default.LOC[geo.lower()] + coord = default.LOC[coord.lower()] + number = str(number) + letter = letter.lower() + return geo + '-' + coord + number + letter def ZoneToRegion(zone): - """Derives the region from a zone name.""" - parts = zone.split('-') - if len(parts) != 3: - raise Error('Cannot derive region from zone "%s"' % zone) - return '-'.join(parts[:2]) + """Derives the region from a zone name.""" + parts = zone.split('-') + if len(parts) != 3: + raise Error('Cannot derive region from zone "%s"' % zone) + return '-'.join(parts[:2]) def FormatException(message): - """Adds more information to the exception.""" - message = ('Exception Type: %s\n' - 'Details: %s\n' - 'Message: %s\n') % (sys.exc_info()[0], - traceback.format_exc(), message) - return message + """Adds more information to the exception.""" + message = ('Exception Type: %s\n Details: %s\n' + 'Message: %s\n') % (sys.exc_info()[0], traceback.format_exc(), message) + return message def Ref(name): - return '$(ref.%s.selfLink)' % name + return '$(ref.%s.selfLink)' % name def RefGroup(name): - return '$(ref.%s.instanceGroup)' % name + return '$(ref.%s.instanceGroup)' % name def GlobalComputeLink(project, collection, name): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - collection, '/', name]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + collection, '/', name]) + def GlobalNetworkLink(project, network): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', - default.NETWORKS, '/', network]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/global/', + default.NETWORKS, '/', network]) def LocalComputeLink(project, zone, key, value): - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', - zone, '/', key, '/', value]) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/zones/', + zone, '/', key, '/', value]) def ReadContext(context, prop_key): - return (context.env['project'], context.properties.get('zone', None), - context.properties[prop_key]) + return (context.env['project'], context.properties.get('zone', None), + context.properties[prop_key]) def MakeLocalComputeLink(context, key, zone=None): - if not zone: - project, zone, value = ReadContext(context, key) - else: - project, _, value = ReadContext(context, key) + if not zone: + project, zone, value = ReadContext(context, key) + else: + project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return LocalComputeLink(project, zone, key + 's', value) + if IsComputeLink(value): + return value + else: + return LocalComputeLink(project, zone, key + 's', value) def MakeGlobalComputeLink(context, key): - project, _, value = ReadContext(context, key) - if IsComputeLink(value): - return value - else: - return GlobalComputeLink(project, key + 's', value) + project, _, value = ReadContext(context, key) + if IsComputeLink(value): + return value + else: + return GlobalComputeLink(project, key + 's', value) + def MakeRegionalSubnetworkLink(project, zone, subnet): - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', subnet]) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', subnet]) def MakeSubnetworkComputeLink(context, key): - project, zone, value = ReadContext(context, key) - region = ZoneToRegion(zone) - return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', - region, '/subnetworks/', value]) + project, zone, value = ReadContext(context, key) + region = ZoneToRegion(zone) + return ''.join([default.COMPUTE_URL_BASE, 'projects/', project, '/regions/', + region, '/subnetworks/', value]) def MakeFQHN(context, name): - return '%s.c.%s.internal' % (name, context.env['project']) + return '%s.c.%s.internal' % (name, context.env['project']) # TODO(victorg): Consider moving this method to a different file def MakeC2DImageLink(name, dev_mode=False): - if IsGlobalProjectShortcut(name) or name.startswith('http'): - return name - else: - if dev_mode: - return 'global/images/%s' % name + if IsGlobalProjectShortcut(name) or name.startswith('http'): + return name else: - return GlobalComputeLink(default.C2D_IMAGES, 'images', name) + if dev_mode: + return 'global/images/%s' % name + else: + return GlobalComputeLink(default.C2D_IMAGES, 'images', name) def IsGlobalProjectShortcut(name): - return name.startswith('projects/') or name.startswith('global/') + return name.startswith('projects/') or name.startswith('global/') def IsComputeLink(name): - return (name.startswith(default.COMPUTE_URL_BASE) or - name.startswith(default.REFERENCE_PREFIX)) + return (name.startswith(default.COMPUTE_URL_BASE) or + name.startswith(default.REFERENCE_PREFIX)) def GetNamesAndTypes(resources_dict): - return [(d['name'], d['type']) for d in resources_dict] + return [(d['name'], d['type']) for d in resources_dict] def SummarizeResources(res_dict): - """Summarizes the name of resources per resource type.""" - result = {} - for res in res_dict: - result.setdefault(res['type'], []).append(res['name']) - return result + """Summarizes the name of resources per resource type.""" + result = {} + for res in res_dict: + result.setdefault(res['type'], []).append(res['name']) + return result def ListPropertyValuesOfType(res_dict, prop, res_type): - """Lists all the values for a property of a certain type.""" - return [r['properties'][prop] for r in res_dict if r['type'] == res_type] + """Lists all the values for a property of a certain type.""" + return [r['properties'][prop] for r in res_dict if r['type'] == res_type] def MakeResource(resource_list, output_list=None): - """Wrapper for a DM template basic spec.""" - content = {'resources': resource_list} - if output_list: - content['outputs'] = output_list - return yaml.dump(content) + """Wrapper for a DM template basic spec.""" + content = {'resources': resource_list} + if output_list: + content['outputs'] = output_list + return yaml.dump(content) def TakeZoneOut(properties): - """Given a properties dictionary, removes the zone specific information.""" - - def _CleanZoneUrl(value): - value = value.split('/')[-1] if IsComputeLink(value) else value - return value - - for name in default.VM_ZONE_PROPERTIES: - if name in properties: - properties[name] = _CleanZoneUrl(properties[name]) - if default.ZONE in properties: - properties.pop(default.ZONE) - if default.BOOTDISK in properties: - properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) - if default.DISKS in properties: - for disk in properties[default.DISKS]: - # Don't touch references to other disks - if default.DISK_SOURCE in disk: - continue - if default.INITIALIZEP in disk: - disk_init = disk[default.INITIALIZEP] - if default.DISKTYPE in disk_init: - disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) + """Given a properties dictionary, removes the zone specific information.""" + + def _CleanZoneUrl(value): + value = value.split('/')[-1] if IsComputeLink(value) else value + return value + + for name in default.VM_ZONE_PROPERTIES: + if name in properties: + properties[name] = _CleanZoneUrl(properties[name]) + if default.ZONE in properties: + properties.pop(default.ZONE) + if default.BOOTDISK in properties: + properties[default.BOOTDISK] = _CleanZoneUrl(properties[default.BOOTDISK]) + if default.DISKS in properties: + for disk in properties[default.DISKS]: + # Don't touch references to other disks + if default.DISK_SOURCE in disk: + continue + if default.INITIALIZEP in disk: + disk_init = disk[default.INITIALIZEP] + if default.DISKTYPE in disk_init: + disk_init[default.DISKTYPE] = _CleanZoneUrl(disk_init[default.DISKTYPE]) def GenerateEmbeddableYaml(yaml_string): - # Because YAML is a space delimited format, we need to be careful about - # embedding one YAML document in another. This function takes in a string in - # YAML format and produces an equivalent YAML representation that can be - # inserted into arbitrary points of another YAML document. It does so by - # printing the YAML string in a single line format. Consistent ordering of - # the string is also guaranteed by using yaml.dump. - yaml_object = yaml.load(yaml_string) - dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) - return dumped_yaml + # Because YAML is a space delimited format, we need to be careful about + # embedding one YAML document in another. This function takes in a string in + # YAML format and produces an equivalent YAML representation that can be + # inserted into arbitrary points of another YAML document. It does so by + # printing the YAML string in a single line format. Consistent ordering of + # the string is also guaranteed by using yaml.dump. + yaml_object = yaml.load(yaml_string) + dumped_yaml = yaml.dump(yaml_object, default_flow_style=True) + return dumped_yaml def FormatErrorsDec(func): - """Decorator to format exceptions if they get raised.""" + """Decorator to format exceptions if they get raised.""" - def FormatErrorsWrap(context): - try: - return func(context) - except Exception as e: - raise Error(FormatException(e.message)) + def FormatErrorsWrap(context): + try: + return func(context) + except Exception as e: + raise Error(FormatException(e.message)) - return FormatErrorsWrap + return FormatErrorsWrap diff --git a/gcp/deployment-packages/single-payg/default.py b/gcp/deployment-packages/single-payg/default.py index 0c7dd919..054d9e52 100755 --- a/gcp/deployment-packages/single-payg/default.py +++ b/gcp/deployment-packages/single-payg/default.py @@ -11,7 +11,7 @@ # 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. -"""Convenience module to hold default constants for C2D components. +"""Convinence module to hold default constants for C2D components. There should not be any logic in this module. Its purpose is to simplify analysis of commonly used GCP and properties names and identify the names @@ -23,7 +23,7 @@ # URL constants COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' -# Deployment Manager constructs +# Deploymen Manager constructs REFERENCE_PREFIX = '$(ref.' # Commonly used in properties namespace @@ -105,8 +105,8 @@ REGION_IGM = 'compute.v1.regionInstanceGroupManager' REGION_AUTOSCALER = 'compute.v1.regionAutoscaler' URL_MAP = 'compute.v1.urlMap' -VPC='compute.v1.network' -VPC_SUBNET='compute.v1.subnetwork' +VPC = 'compute.v1.network' +VPC_SUBNET = 'compute.v1.subnetwork' # Also Known As constants AKA = { diff --git a/gcp/deployment-packages/single-payg/images.py b/gcp/deployment-packages/single-payg/images.py index 34855e97..a452b68e 100755 --- a/gcp/deployment-packages/single-payg/images.py +++ b/gcp/deployment-packages/single-payg/images.py @@ -1,34 +1,34 @@ IMAGES = { - "check-point-r8120-payg": "check-point-r8120-payg-631-991001383-v20230907", - "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001383-v20230907", - "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001383-v20230907", - "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001383-v20230907", - "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001383-v20230907", - "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001383-v20230907", - "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001383-v20230907", - "check-point-r8120-byol": "check-point-r8120-byol-631-991001383-v20230907", - "check-point-r8110-payg": "check-point-r8110-payg-335-991001383-v20230907", - "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001383-v20230907", - "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001383-v20230907", - "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001383-v20230907", - "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001383-v20230907", - "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001383-v20230907", - "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001383-v20230907", - "check-point-r8110-byol": "check-point-r8110-byol-335-991001383-v20230907", - "check-point-r81-payg": "check-point-r81-payg-392-991001383-v20230907", - "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001383-v20230907", - "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001383-v20230907", - "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001383-v20230907", - "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001383-v20230907", - "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001383-v20230907", - "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001383-v20230907", - "check-point-r81-byol": "check-point-r81-byol-392-991001383-v20230907", - "check-point-r8040-payg": "check-point-r8040-payg-294-991001383-v20230907", - "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001383-v20230907", - "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001383-v20230907", - "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001383-v20230907", - "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001383-v20230907", - "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001383-v20230907", - "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001383-v20230907", - "check-point-r8040-byol": "check-point-r8040-byol-294-991001383-v20230907" -} + "check-point-r8120-payg": "check-point-r8120-payg-631-991001475-v20231221", + "check-point-r8120-gw-payg-single": "check-point-r8120-gw-payg-single-631-991001475-v20231221", + "check-point-r8120-gw-payg-mig": "check-point-r8120-gw-payg-mig-631-991001475-v20231221", + "check-point-r8120-gw-payg-cluster": "check-point-r8120-gw-payg-cluster-631-991001475-v20231221", + "check-point-r8120-gw-byol-single": "check-point-r8120-gw-byol-single-631-991001475-v20231221", + "check-point-r8120-gw-byol-mig": "check-point-r8120-gw-byol-mig-631-991001475-v20231221", + "check-point-r8120-gw-byol-cluster": "check-point-r8120-gw-byol-cluster-631-991001475-v20231221", + "check-point-r8120-byol": "check-point-r8120-byol-631-991001475-v20231221", + "check-point-r8110-payg": "check-point-r8110-payg-335-991001475-v20231221", + "check-point-r8110-gw-payg-single": "check-point-r8110-gw-payg-single-335-991001475-v20231221", + "check-point-r8110-gw-payg-mig": "check-point-r8110-gw-payg-mig-335-991001475-v20231221", + "check-point-r8110-gw-payg-cluster": "check-point-r8110-gw-payg-cluster-335-991001475-v20231221", + "check-point-r8110-gw-byol-single": "check-point-r8110-gw-byol-single-335-991001475-v20231221", + "check-point-r8110-gw-byol-mig": "check-point-r8110-gw-byol-mig-335-991001475-v20231221", + "check-point-r8110-gw-byol-cluster": "check-point-r8110-gw-byol-cluster-335-991001475-v20231221", + "check-point-r8110-byol": "check-point-r8110-byol-335-991001475-v20231221", + "check-point-r81-payg": "check-point-r81-payg-392-991001475-v20231221", + "check-point-r81-gw-payg-single": "check-point-r81-gw-payg-single-392-991001475-v20231221", + "check-point-r81-gw-payg-mig": "check-point-r81-gw-payg-mig-392-991001475-v20231221", + "check-point-r81-gw-payg-cluster": "check-point-r81-gw-payg-cluster-392-991001475-v20231221", + "check-point-r81-gw-byol-single": "check-point-r81-gw-byol-single-392-991001475-v20231221", + "check-point-r81-gw-byol-mig": "check-point-r81-gw-byol-mig-392-991001475-v20231221", + "check-point-r81-gw-byol-cluster": "check-point-r81-gw-byol-cluster-392-991001475-v20231221", + "check-point-r81-byol": "check-point-r81-byol-392-991001475-v20231221", + "check-point-r8040-payg": "check-point-r8040-payg-294-991001475-v20231221", + "check-point-r8040-gw-payg-single": "check-point-r8040-gw-payg-single-294-991001475-v20231221", + "check-point-r8040-gw-payg-mig": "check-point-r8040-gw-payg-mig-294-991001475-v20231221", + "check-point-r8040-gw-payg-cluster": "check-point-r8040-gw-payg-cluster-294-991001475-v20231221", + "check-point-r8040-gw-byol-single": "check-point-r8040-gw-byol-single-294-991001475-v20231221", + "check-point-r8040-gw-byol-mig": "check-point-r8040-gw-byol-mig-294-991001475-v20231221", + "check-point-r8040-gw-byol-cluster": "check-point-r8040-gw-byol-cluster-294-991001475-v20231221", + "check-point-r8040-byol": "check-point-r8040-byol-294-991001475-v20231221" +} \ No newline at end of file diff --git a/gcp/deployment-packages/single-payg/password.py b/gcp/deployment-packages/single-payg/password.py index 273210a6..bfe40f5c 100755 --- a/gcp/deployment-packages/single-payg/password.py +++ b/gcp/deployment-packages/single-payg/password.py @@ -63,73 +63,71 @@ class InputError(Exception): - """Raised when input properties are unexpected.""" + """Raised when input properties are unexpected.""" def GenerateConfig(context): - """Entry function to generate the DM config.""" - props = context.properties - length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) - include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) + """Entry function to generate the DM config.""" + props = context.properties + length = props.setdefault(PROPERTY_LENGTH, MIN_LENGTH) + include_symbols = props.setdefault(PROPERTY_INCLUDE_SYMBOLS, False) - if not isinstance(include_symbols, bool): - raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) + if not isinstance(include_symbols, bool): + raise InputError('%s must be a boolean' % PROPERTY_INCLUDE_SYMBOLS) - content = { + content = { 'resources': [], 'outputs': [{ 'name': 'password', 'value': GeneratePassword(length, include_symbols) }] - } - return yaml.dump(content) + } + return yaml.dump(content) def GeneratePassword(length=8, include_symbols=False): - """Generates a random password.""" - if length < MIN_LENGTH: - raise InputError('Password length must be at least %d' % MIN_LENGTH) - - candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols - else CANDIDATES_WITHOUT_SYMBOLS) - categories = (CATEGORIES_WITH_SYMBOLS if include_symbols - else CATEGORIES_WITHOUT_SYMBOLS) - - # Generates up to the specified length minus the number of categories. - # Then inserts one character for each category, ensuring that the character - # satisfy the category if the generated string hasn't already. - generated = ([random.choice(ALPHABET)] + - [random.choice(candidates) - for _ in range(length - 1 - len(categories))]) - for category in categories: - _InsertAndEnsureSatisfaction(generated, category, candidates) - return ''.join(generated) + """Generates a random password.""" + if length < MIN_LENGTH: + raise InputError('Password length must be at least %d' % MIN_LENGTH) + + candidates = (CANDIDATES_WITH_SYMBOLS if include_symbols + else CANDIDATES_WITHOUT_SYMBOLS) + categories = (CATEGORIES_WITH_SYMBOLS if include_symbols + else CATEGORIES_WITHOUT_SYMBOLS) + + # Generates up to the specified length minus the number of categories. + # Then inserts one character for each category, ensuring that the character + # satisfy the category if the generated string hasn't already. + generated = ([random.choice(ALPHABET)] + [random.choice(candidates) + for _ in range(length - 1 - len(categories))]) + for category in categories: + _InsertAndEnsureSatisfaction(generated, category, candidates) + return ''.join(generated) def _InsertAndEnsureSatisfaction(generated, required, all_candidates): - """Inserts 1 char into generated, satisfying required if not already. - - If the required characters are not already in the generated string, one will - be inserted. If any required character is already in the generated string, a - random character from all_candidates will be inserted. The insertion happens - at a random location but not at the beginning. - - Args: - generated: the string to be modified. - required: list of required characters to check for. - all_candidates: list of characters to choose from if the required characters - are already satisfied. - """ - if set(generated).isdisjoint(required): - # Not yet satisfied. Insert a required candidate. - _InsertInto(generated, required) - else: - # Already satisfied. Insert any candidate. - _InsertInto(generated, all_candidates) + """Inserts 1 char into generated, satisfying required if not already. + + If the required characters are not already in the generated string, one will + be inserted. If any required character is already in the generated string, a + random character from all_candidates will be inserted. The insertion happens + at a random location but not at the beginning. + + Args: + generated: the string to be modified. + required: list of required characters to check for. + all_candidates: list of characters to choose from if the required characters + are already satisfied. + """ + if set(generated).isdisjoint(required): + # Not yet satisfied. Insert a required candidate. + _InsertInto(generated, required) + else: + # Already satisfied. Insert any candidate. + _InsertInto(generated, all_candidates) def _InsertInto(generated, candidates): - """Inserts a random candidate into a random non-zero index of generated.""" - # Avoids inserting at index 0, since the first character follows its own rule. - generated.insert(random.randint(1, len(generated) - 1), - random.choice(candidates)) + """Inserts a random candidate into a random non-zero index of generated.""" + # Avoids inserting at index 0, since the first character follows its own rule. + generated.insert(random.randint(1, len(generated) - 1), random.choice(candidates))