# Copyright 2017 The Forseti Security Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A Compute InstanceGroup.
See:
https://cloud.google.com/compute/docs/reference/latest/instanceGroups
"""
from builtins import object
import json
import os
from google.cloud.forseti.common.gcp_type import key
# pylint: disable=too-many-instance-attributes
[docs]class InstanceGroup(object):
"""Represents InstanceGroup resource."""
def __init__(self, **kwargs):
"""InstanceGroup resource.
Args:
**kwargs (dict): The object's attributes.
"""
self.id = kwargs.get('id')
self.creation_timestamp = kwargs.get('creation_timestamp')
self.description = kwargs.get('description')
self.instance_urls = kwargs.get('instance_urls')
self.name = kwargs.get('name')
self.named_ports = kwargs.get('named_ports')
self.network = kwargs.get('network')
self.project_id = kwargs.get('project_id')
self.region = kwargs.get('region')
self.resource_id = kwargs.get('id')
self.size = kwargs.get('size')
self.subnetwork = kwargs.get('subnetwork')
self.zone = kwargs.get('zone')
self.project_id = kwargs.get('project_id')
self._json = kwargs.get('raw_instance_group')
[docs] @classmethod
def from_dict(cls, instance_group, project_id=None):
"""Creates an InstanceGroup from an instance group dict.
Args:
instance_group (dict): An instance group resource dict.
project_id (str): A project id for the resource.
Returns:
InstanceGroup: A new InstanceGroup object.
"""
kwargs = {'project_id': project_id,
'id': instance_group.get('id'),
'creation_timestamp': instance_group.get('creationTimestamp'),
'name': instance_group.get('name'),
'description': instance_group.get('description'),
'instance_urls': instance_group.get('instance_urls', []),
'named_ports': instance_group.get('namedPorts', []),
'network': instance_group.get('network'),
'region': instance_group.get('region'),
'size': instance_group.get('size'),
'subnetwork': instance_group.get('subnetwork'),
'zone': instance_group.get('zone'),
'raw_instance_group': json.dumps(
instance_group, sort_keys=True)}
return cls(**kwargs)
[docs] @staticmethod
def from_json(json_string, project_id=None):
"""Creates an InstanceGroup from an instance group JSON string.
Args:
json_string (str): A json string representing the instance group.
project_id (str): A project id for the resource.
Returns:
InstanceGroup: A new InstanceGroup object.
"""
instance_group = json.loads(json_string)
return InstanceGroup.from_dict(instance_group, project_id)
[docs] def _create_json_str(self):
"""Creates a json string based on the object attributes.
Returns:
str: json str.
"""
resource_dict = {
'id': self.id,
'creationTimestamp': self.creation_timestamp,
'name': self.name,
'description': self.description,
'instance_urls': self.instance_urls,
'namedPorts': self.named_ports,
'network': self.network,
'region': self.region,
'size': self.size,
'subnetwork': self.subnetwork,
'zone': self.zone}
# Strip out empty values
resource_dict = dict((k, v) for k, v in
list(resource_dict.items()) if v)
return json.dumps(resource_dict, sort_keys=True)
@property
def json(self):
"""Returns the json string representation of the resource.
Returns:
str: json str.
"""
if not self._json:
self._json = self._create_json_str()
return self._json
@property
def key(self):
"""Returns a Key identifying the object.
Returns:
Key: the key
"""
return Key.from_args(self.project_id, self.name,
region=self.region,
zone=self.zone)
KEY_OBJECT_KIND = 'InstanceGroup'
[docs]class Key(key.Key):
"""An identifier for a specific instance group."""
[docs] @staticmethod
def from_args(project_id, name, region=None, zone=None):
"""Construct a Key from specific values.
One and only one of (region, zone) must be specified.
Args:
project_id (str): project_id
name (str): name
region (str): region
zone (str): zone
Returns:
Key: the key
Raises:
ValueError: an invalid combination of arguments was provided.
"""
if not bool(region) ^ bool(zone):
raise ValueError('Key must specify one of either region or zone')
if region:
region = os.path.basename(region)
if zone:
zone = os.path.basename(zone)
return Key(KEY_OBJECT_KIND, {
'project_id': project_id,
'region': region,
'zone': zone,
'name': name})
[docs] @classmethod
def from_url(cls, url):
"""Construct a Key from a URL.
Args:
url (str): Object reference URL
Returns:
Key: the key
Raises:
ValueError: Required parameters are missing.
"""
obj = Key._from_url(KEY_OBJECT_KIND,
{'projects': 'project_id',
'regions': 'region',
'zones': 'zone',
'instanceGroups': 'name'},
url)
if (not obj.project_id or
not obj.name or
not bool(obj.zone) ^ bool(obj.region)):
raise ValueError('Invalid fields in URL %r' % url)
return obj
@property
def project_id(self):
"""Object property: project_id
Returns:
str: project_id
"""
return self._path_component('project_id')
@property
def region(self):
"""Object property: region
Returns:
str: region
"""
return self._path_component('region')
@property
def zone(self):
"""Object property: zone
Returns:
str: zone
"""
return self._path_component('zone')
@property
def name(self):
"""Object property: name
Returns:
str: name
"""
return self._path_component('name')