# coding: utf-8

# (C) Copyright IBM Corp. 2020.
#
# 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.

# IBM OpenAPI SDK Code Generator Version: 3.12.0-64fe8d3f-20200820-144050
"""
The IBM Cloud Virtual Private Cloud (VPC) API can be used to programmatically provision
and manage infrastructure resources, including virtual server instances, subnets, volumes,
and load balancers.
"""

from datetime import datetime
from enum import Enum
from typing import Dict, List
import base64
import json
import sys

from ibm_cloud_sdk_core import BaseService, DetailedResponse
from ibm_cloud_sdk_core.authenticators.authenticator import Authenticator
from ibm_cloud_sdk_core.get_authenticator import get_authenticator_from_environment
from ibm_cloud_sdk_core.utils import convert_model, datetime_to_string, string_to_datetime

from .common import get_sdk_headers

##############################################################################
# Service
##############################################################################


class VpcV1(BaseService):
    """The vpc V1 service."""

    DEFAULT_SERVICE_URL = 'https://us-south.iaas.cloud.ibm.com/v1'
    DEFAULT_SERVICE_NAME = 'vpc'

    @classmethod
    def new_instance(
        cls,
        version: str = '2020-08-25',
        service_name: str = DEFAULT_SERVICE_NAME,
        generation: int = 2,
    ) -> 'VpcV1':
        """
        Return a new client for the vpc service using the specified parameters and
               external configuration.

        :param str version: Requests the version of the API as of a date in the
               format `YYYY-MM-DD`. Any date up to the current date may be provided.
               Specify the current date to request the latest version.
        """

        authenticator = get_authenticator_from_environment(service_name)
        service = cls(
            version,
            authenticator,
            generation,
        )
        service.configure_service(service_name)
        return service

    def __init__(
        self,
        version: str = '2020-08-25',
        authenticator: Authenticator = None,
        generation: int = 2,
    ) -> None:
        """
        Construct a new client for the vpc service.

        :param str version: Requests the version of the API as of a date in the
               format `YYYY-MM-DD`. Any date up to the current date may be provided.
               Specify the current date to request the latest version.

        :param Authenticator authenticator: The authenticator specifies the authentication mechanism.
               Get up to date information from https://github.com/IBM/python-sdk-core/blob/master/README.md
               about initializing the authenticator of your choice.
        """

        BaseService.__init__(self,
                             service_url=self.DEFAULT_SERVICE_URL,
                             authenticator=authenticator)
        self.version = version
        self.generation = generation

    #########################
    # VPCs
    #########################

    def list_vpcs(self,
                  *,
                  start: str = None,
                  limit: int = None,
                  resource_group_id: str = None,
                  classic_access: bool = None,
                  **kwargs) -> DetailedResponse:
        """
        List all VPCs.

        This request lists all VPCs. A VPC is a virtual network that belongs to an account
        and provides logical isolation from other networks. A VPC is made up of resources
        in one or more zones. VPCs are regional, and each VPC can contain resources in
        multiple zones in a region.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param bool classic_access: (optional) The `classic_access` parameter
               filters the returned collection by the supplied field. If the supplied
               field is `true`, only Classic Access VPCs will be returned. If the supplied
               field is `false`, only VPCs without Classic Access will be returned.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPCCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_vpcs')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'classic_access': classic_access
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_vpc(self,
                   *,
                   name: str = None,
                   address_prefix_management: str = None,
                   classic_access: bool = None,
                   resource_group: 'ResourceGroupIdentity' = None,
                   **kwargs) -> DetailedResponse:
        """
        Create a VPC.

        This request creates a new VPC from a VPC prototype object. The prototype object
        is structured in the same way as a retrieved VPC, and contains the information
        necessary to create the new VPC.

        :param str name: (optional) The unique user-defined name for this VPC. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param str address_prefix_management: (optional) Indicates whether a
               default address prefix should be automatically created for each zone in
               this VPC. If `manual`, this VPC will be created with no default address
               prefixes.
        :param bool classic_access: (optional) Indicates whether this VPC should be
               connected to Classic Infrastructure. If true, this VPC's resources will
               have private network connectivity to the account's Classic Infrastructure
               resources. Only one VPC, per region, may be connected in this way. This
               value is set at creation and subsequently immutable.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPC` object
        """

        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_vpc')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'address_prefix_management': address_prefix_management,
            'classic_access': classic_access,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpc(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified VPC.

        This request deletes a VPC. This operation cannot be reversed. For this request to
        succeed, the VPC must not contain any instances, subnets, or public gateways. All
        security groups and network ACLs associated with the VPC are automatically
        deleted. All flow log collectors with `auto_delete` set to `true` targeting the
        VPC or any resource in the VPC are automatically deleted.

        :param str id: The VPC identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_vpc')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpcs/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified VPC.

        This request retrieves a single VPC specified by the identifier in the URL.

        :param str id: The VPC identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPC` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_vpc')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpc(self,
                   id: str,
                   *,
                   name: str = None,
                   **kwargs) -> DetailedResponse:
        """
        Update specified VPC.

        This request updates a VPC's name.

        :param str id: The VPC identifier.
        :param str name: (optional) The unique user-defined name for this VPC.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPC` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_vpc')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def get_vpc_default_network_acl(self, id: str,
                                    **kwargs) -> DetailedResponse:
        """
        Retrieve a VPC's default network ACL.

        This request retrieves the default network ACL for the VPC specified by the
        identifier in the URL. The default network ACL is applied to any new subnets in
        the VPC which do not specify a network ACL.

        :param str id: The VPC identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DefaultNetworkACL` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_vpc_default_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/default_network_acl'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc_default_security_group(self, id: str,
                                       **kwargs) -> DetailedResponse:
        """
        Retrieve a VPC's default security group.

        This request retrieves the default security group for the VPC specified by the
        identifier in the URL. The default security group is applied to any new network
        interfaces in the VPC that do not specify a security group.

        :param str id: The VPC identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DefaultSecurityGroup` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_vpc_default_security_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/default_security_group'.format(
            *self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_vpc_address_prefixes(self,
                                  vpc_id: str,
                                  *,
                                  start: str = None,
                                  limit: int = None,
                                  **kwargs) -> DetailedResponse:
        """
        List all address pool prefixes for a VPC.

        This request lists all address pool prefixes for a VPC.

        :param str vpc_id: The VPC identifier.
        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `AddressPrefixCollection` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_vpc_address_prefixes')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/address_prefixes'.format(
            *self.encode_path_vars(vpc_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_vpc_address_prefix(self,
                                  vpc_id: str,
                                  cidr: str,
                                  zone: 'ZoneIdentity',
                                  *,
                                  name: str = None,
                                  is_default: bool = None,
                                  **kwargs) -> DetailedResponse:
        """
        Create an address pool prefix.

        This request creates a new prefix from a prefix prototype object. The prototype
        object is structured in the same way as a retrieved prefix, and contains the
        information necessary to create the new prefix.

        :param str vpc_id: The VPC identifier.
        :param str cidr: The IPv4 range of the address prefix, expressed in CIDR
               format. The request must not overlap with any existing address prefixes in
               the VPC, and must fall within the [RFC
               1918](https://tools.ietf.org/html/rfc1918) address ranges. The prefix
               length of the address prefix's CIDR must be between `/8` (16,777,216
               addresses) and `/29` (8 addresses).
        :param ZoneIdentity zone: The zone this address prefix is to belong to.
        :param str name: (optional) The user-defined name for this address prefix.
               Names must be unique within the VPC the address prefix resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param bool is_default: (optional) Indicates whether this is the default
               prefix for this zone in this VPC. If true, this prefix will become the
               default prefix for this zone in this VPC. This fails if the VPC currently
               has a default address prefix for this zone.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `AddressPrefix` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if cidr is None:
            raise ValueError('cidr must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        zone = convert_model(zone)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_vpc_address_prefix')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'cidr': cidr,
            'zone': zone,
            'name': name,
            'is_default': is_default
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/address_prefixes'.format(
            *self.encode_path_vars(vpc_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpc_address_prefix(self, vpc_id: str, id: str,
                                  **kwargs) -> DetailedResponse:
        """
        Delete specified address pool prefix.

        This request deletes a prefix. This operation cannot be reversed. The request will
        fail if any subnets use addresses from this prefix.

        :param str vpc_id: The VPC identifier.
        :param str id: The prefix identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_vpc_address_prefix')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpcs/{0}/address_prefixes/{1}'.format(
            *self.encode_path_vars(vpc_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc_address_prefix(self, vpc_id: str, id: str,
                               **kwargs) -> DetailedResponse:
        """
        Retrieve specified address pool prefix.

        This request retrieves a single prefix specified by the identifier in the URL.

        :param str vpc_id: The VPC identifier.
        :param str id: The prefix identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `AddressPrefix` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_vpc_address_prefix')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/address_prefixes/{1}'.format(
            *self.encode_path_vars(vpc_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpc_address_prefix(self,
                                  vpc_id: str,
                                  id: str,
                                  *,
                                  name: str = None,
                                  is_default: bool = None,
                                  **kwargs) -> DetailedResponse:
        """
        Update an address pool prefix.

        This request updates a prefix with the information in a provided prefix patch. The
        prefix patch object is structured in the same way as a retrieved prefix and
        contains only the information to be updated.

        :param str vpc_id: The VPC identifier.
        :param str id: The prefix identifier.
        :param str name: (optional) The user-defined name for this address prefix.
               Names must be unique within the VPC the address prefix resides in.
        :param bool is_default: (optional) Indicates whether this is the default
               prefix for this zone in this VPC. Updating to true makes this prefix the
               default prefix for this zone in this VPC, provided the VPC currently has no
               default address prefix for this zone. Updating to false removes the default
               prefix for this zone in this VPC.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `AddressPrefix` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_vpc_address_prefix')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name, 'is_default': is_default}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/address_prefixes/{1}'.format(
            *self.encode_path_vars(vpc_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_vpc_routes(self,
                        vpc_id: str,
                        *,
                        zone_name: str = None,
                        **kwargs) -> DetailedResponse:
        """
        List all routes in the VPC's default routing table.

        This request retrieves routes in the VPC's default routing table. For
        compatibility, routes with `action` values other than `deliver` are omitted. Each
        route is zone-specific and directs any packets matching its destination CIDR block
        to a `next_hop` IP address. The most specific route matching a packet's
        destination will be used. If multiple equally-specific routes exist, traffic will
        be distributed across them.

        :param str vpc_id: The VPC identifier.
        :param str zone_name: (optional) Filters the collection to resources in the
               zone with the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteCollection` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_vpc_routes')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'zone.name': zone_name
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/routes'.format(*self.encode_path_vars(vpc_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_vpc_route(self,
                         vpc_id: str,
                         next_hop: 'RouteNextHopPrototype',
                         destination: str,
                         zone: 'ZoneIdentity',
                         *,
                         name: str = None,
                         **kwargs) -> DetailedResponse:
        """
        Create a route in the VPC's default routing table.

        This request creates a new route in the VPC's default routing table. The route
        prototype object is structured in the same way as a retrieved route, and contains
        the information necessary to create the new route. The request will fail if the
        new route will cause a loop.

        :param str vpc_id: The VPC identifier.
        :param RouteNextHopPrototype next_hop: The next hop that packets will be
               delivered to.
        :param str destination: The destination of the route. Must not overlap with
               destinations for existing user-defined routes within the VPC.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str name: (optional) The user-defined name for this route. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               Names must be unique within the VPC routing table the route resides in.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Route` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if next_hop is None:
            raise ValueError('next_hop must be provided')
        if destination is None:
            raise ValueError('destination must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        next_hop = convert_model(next_hop)
        zone = convert_model(zone)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_vpc_route')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'next_hop': next_hop,
            'destination': destination,
            'zone': zone,
            'name': name
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/routes'.format(*self.encode_path_vars(vpc_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpc_route(self, vpc_id: str, id: str,
                         **kwargs) -> DetailedResponse:
        """
        Delete the specified route in the VPC's default routing table.

        This request deletes a route. This operation cannot be reversed.

        :param str vpc_id: The VPC identifier.
        :param str id: The route identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_vpc_route')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpcs/{0}/routes/{1}'.format(*self.encode_path_vars(vpc_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc_route(self, vpc_id: str, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified route in the VPC's default routing table.

        This request retrieves a single route specified by the identifier in the URL.

        :param str vpc_id: The VPC identifier.
        :param str id: The route identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Route` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_vpc_route')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/routes/{1}'.format(*self.encode_path_vars(vpc_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpc_route(self,
                         vpc_id: str,
                         id: str,
                         *,
                         name: str = None,
                         **kwargs) -> DetailedResponse:
        """
        Update the specified route in the VPC's default routing table.

        This request updates a route with the information in a provided route patch. The
        route patch object is structured in the same way as a retrieved route and contains
        only the information to be updated.

        :param str vpc_id: The VPC identifier.
        :param str id: The route identifier.
        :param str name: (optional) The user-defined name for this route. Names
               must be unique within the VPC routing table the route resides in.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Route` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_vpc_route')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpcs/{0}/routes/{1}'.format(*self.encode_path_vars(vpc_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Subnets
    #########################

    def list_subnets(self,
                     *,
                     start: str = None,
                     limit: int = None,
                     resource_group_id: str = None,
                     **kwargs) -> DetailedResponse:
        """
        List all subnets.

        This request lists all subnets in the region. Subnets are contiguous ranges of IP
        addresses specified in CIDR block notation. Each subnet is within a particular
        zone and cannot span multiple zones or regions.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SubnetCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_subnets')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_subnet(self, subnet_prototype: 'SubnetPrototype',
                      **kwargs) -> DetailedResponse:
        """
        Create a subnet.

        This request creates a new subnet from a subnet prototype object. The prototype
        object is structured in the same way as a retrieved subnet, and contains the
        information necessary to create the new subnet. For this request to succeed, the
        prototype's CIDR block must not overlap with an existing subnet in the VPC.

        :param SubnetPrototype subnet_prototype: The subnet prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Subnet` object
        """

        if subnet_prototype is None:
            raise ValueError('subnet_prototype must be provided')
        if isinstance(subnet_prototype, SubnetPrototype):
            subnet_prototype = convert_model(subnet_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_subnet')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(subnet_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_subnet(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified subnet.

        This request deletes a subnet. This operation cannot be reversed. For this request
        to succeed, the subnet must not be referenced by any network interfaces, VPN
        gateways, or load balancers. A delete operation automatically detaches the subnet
        from any network ACLs, public gateways, or endpoint gateways. All flow log
        collectors with `auto_delete` set to
        `true` targeting the subnet or any resource in the subnet are automatically
        deleted.

        :param str id: The subnet identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_subnet')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/subnets/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_subnet(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified subnet.

        This request retrieves a single subnet specified by the identifier in the URL.

        :param str id: The subnet identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Subnet` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_subnet')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_subnet(self,
                      id: str,
                      *,
                      name: str = None,
                      network_acl: 'NetworkACLIdentity' = None,
                      public_gateway: 'PublicGatewayIdentity' = None,
                      **kwargs) -> DetailedResponse:
        """
        Update specified subnet.

        This request updates a subnet with the information in a provided subnet patch. The
        subnet patch object is structured in the same way as a retrieved subnet and
        contains only the information to be updated.

        :param str id: The subnet identifier.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Subnet` object
        """

        if id is None:
            raise ValueError('id must be provided')
        if network_acl is not None:
            network_acl = convert_model(network_acl)
        if public_gateway is not None:
            public_gateway = convert_model(public_gateway)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_subnet')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'network_acl': network_acl,
            'public_gateway': public_gateway
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def get_subnet_network_acl(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a subnet's attached network ACL.

        This request retrieves the network ACL attached to the subnet specified by the
        identifier in the URL.

        :param str id: The subnet identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACL` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_subnet_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets/{0}/network_acl'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def replace_subnet_network_acl(self, id: str,
                                   network_acl_identity: 'NetworkACLIdentity',
                                   **kwargs) -> DetailedResponse:
        """
        Attach a network ACL to a subnet.

        This request attaches the network ACL, specified in the request body, to the
        subnet specified by the subnet identifier in the URL. This replaces the existing
        network ACL on the subnet.

        :param str id: The subnet identifier.
        :param NetworkACLIdentity network_acl_identity: The network ACL identity.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACL` object
        """

        if id is None:
            raise ValueError('id must be provided')
        if network_acl_identity is None:
            raise ValueError('network_acl_identity must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='replace_subnet_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(network_acl_identity)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets/{0}/network_acl'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def unset_subnet_public_gateway(self, id: str,
                                    **kwargs) -> DetailedResponse:
        """
        Detach a public gateway from a subnet.

        This request detaches the public gateway from the subnet specified by the subnet
        identifier in the URL.

        :param str id: The subnet identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='unset_subnet_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/subnets/{0}/public_gateway'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_subnet_public_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a subnet's attached public gateway.

        This request retrieves the public gateway attached to the subnet specified by the
        identifier in the URL.

        :param str id: The subnet identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGateway` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_subnet_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets/{0}/public_gateway'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def set_subnet_public_gateway(
            self, id: str, public_gateway_identity: 'PublicGatewayIdentity',
            **kwargs) -> DetailedResponse:
        """
        Attach a public gateway to a subnet.

        This request attaches the public gateway, specified in the request body, to the
        subnet specified by the subnet identifier in the URL. The public gateway must have
        the same VPC and zone as the subnet.

        :param str id: The subnet identifier.
        :param PublicGatewayIdentity public_gateway_identity: The public gateway
               identity.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGateway` object
        """

        if id is None:
            raise ValueError('id must be provided')
        if public_gateway_identity is None:
            raise ValueError('public_gateway_identity must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='set_subnet_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(public_gateway_identity)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/subnets/{0}/public_gateway'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Images
    #########################

    def list_images(self,
                    *,
                    start: str = None,
                    limit: int = None,
                    resource_group_id: str = None,
                    name: str = None,
                    visibility: str = None,
                    **kwargs) -> DetailedResponse:
        """
        List all images.

        This request lists all provisionable images available in the region. An image
        provides source data for a volume. Images are either system-provided, or created
        from another source, such as importing from object storage.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param str name: (optional) Filters the collection to resources with the
               exact specified name.
        :param str visibility: (optional) Filters the collection to images with the
               specified `visibility`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ImageCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_images')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'name': name,
            'visibility': visibility
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/images'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_image(self, image_prototype: 'ImagePrototype',
                     **kwargs) -> DetailedResponse:
        """
        Create an image.

        This request creates a new image from an image prototype object. The prototype
        object is structured in the same way as a retrieved image, and contains the
        information necessary to create the new image. A URL to the image file on object
        storage must be provided.

        :param ImagePrototype image_prototype: The image prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Image` object
        """

        if image_prototype is None:
            raise ValueError('image_prototype must be provided')
        if isinstance(image_prototype, ImagePrototype):
            image_prototype = convert_model(image_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_image')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(image_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/images'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_image(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified image.

        This request deletes an image. This operation cannot be reversed. System-provided
        images are not allowed to be deleted. An image with a `status` of `pending`,
        `tentative`, or `deleting` cannot be deleted.

        :param str id: The image identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_image')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/images/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_image(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified image.

        This request retrieves a single image specified by the identifier in the URL.

        :param str id: The image identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Image` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_image')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/images/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_image(self,
                     id: str,
                     *,
                     name: str = None,
                     **kwargs) -> DetailedResponse:
        """
        Update specified image.

        This request updates an image with the information in a provided image patch. The
        image patch object is structured in the same way as a retrieved image and contains
        only the information to be updated. System-provided images are not allowed to be
        updated. An image with a `status` of `deleting` cannot be updated.

        :param str id: The image identifier.
        :param str name: (optional) The unique user-defined name for this image.
               Names starting with "ibm-" are not allowed.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Image` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_image')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/images/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_operating_systems(self,
                               *,
                               start: str = None,
                               limit: int = None,
                               **kwargs) -> DetailedResponse:
        """
        Retrieves all operating systems.

        This request retrieves all operating systems.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `OperatingSystemCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_operating_systems')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/operating_systems'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_operating_system(self, name: str, **kwargs) -> DetailedResponse:
        """
        Retrieves an operating system.

        This request retrieves a single operating system specified by the name in the URL.

        :param str name: The operating system name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `OperatingSystem` object
        """

        if name is None:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_operating_system')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/operating_systems/{0}'.format(*self.encode_path_vars(name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    #########################
    # Keys
    #########################

    def list_keys(self,
                  *,
                  resource_group_id: str = None,
                  **kwargs) -> DetailedResponse:
        """
        List all keys.

        This request lists all keys. A key contains a public SSH key which may be
        installed on instances when they are created. Private keys are not stored.

        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `KeyCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_keys')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'resource_group.id': resource_group_id
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/keys'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_key(self,
                   public_key: str,
                   *,
                   name: str = None,
                   type: str = None,
                   resource_group: 'ResourceGroupIdentity' = None,
                   **kwargs) -> DetailedResponse:
        """
        Create a key.

        This request creates a new SSH key from an key prototype object. The prototype
        object is structured in the same way as a retrieved key, and contains the
        information necessary to create the new key. The public key value must be
        provided.

        :param str public_key: A unique public SSH key to import, encoded in PEM
               format. The key (prior to encoding) must be either 2048 or 4096 bits long.
        :param str name: (optional) The unique user-defined name for this key. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param str type: (optional) The cryptosystem used by this key.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Key` object
        """

        if public_key is None:
            raise ValueError('public_key must be provided')
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_key')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'public_key': public_key,
            'name': name,
            'type': type,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/keys'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_key(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified key.

        This request deletes a key. This operation cannot be reversed.

        :param str id: The key identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_key')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/keys/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_key(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified key.

        This request retrieves a single key specified by the identifier in the URL.

        :param str id: The key identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Key` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_key')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/keys/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_key(self,
                   id: str,
                   *,
                   name: str = None,
                   **kwargs) -> DetailedResponse:
        """
        Update specified key.

        This request updates a key's name.

        :param str id: The key identifier.
        :param str name: (optional) The user-defined name for this key.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Key` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_key')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/keys/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Instances
    #########################

    def list_instance_profiles(self, **kwargs) -> DetailedResponse:
        """
        List all instance profiles.

        This request lists all instance profiles available in the region. An instance
        profile specifies the performance characteristics and pricing model for an
        instance.

        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceProfileCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_instance_profiles')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance/profiles'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_profile(self, name: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified instance profile.

        This request retrieves a single instance profile specified by the name in the URL.

        :param str name: The instance profile name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceProfile` object
        """

        if name is None:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_instance_profile')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance/profiles/{0}'.format(*self.encode_path_vars(name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_instance_templates(self, **kwargs) -> DetailedResponse:
        """
        Get instance templates.

        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceTemplateCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_instance_templates')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance/templates'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_template(
            self, instance_template_prototype: 'InstanceTemplatePrototype',
            **kwargs) -> DetailedResponse:
        """
        Create an instance template.

        This request creates a new instance template.

        :param InstanceTemplatePrototype instance_template_prototype: The instance
               template prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceTemplate` object
        """

        if instance_template_prototype is None:
            raise ValueError('instance_template_prototype must be provided')
        if isinstance(instance_template_prototype, InstanceTemplatePrototype):
            instance_template_prototype = convert_model(
                instance_template_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_instance_template')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(instance_template_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance/templates'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_template(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified instance template.

        This request deletes the instance template. This operation cannot be reversed.

        :param str id: The instance template identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_instance_template')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance/templates/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_template(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified instance template.

        :param str id: The instance template identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceTemplate` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_instance_template')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance/templates/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_template(self,
                                 id: str,
                                 *,
                                 name: str = None,
                                 **kwargs) -> DetailedResponse:
        """
        Update specified instance template.

        This request updates an instance template with the information provided in the
        instance template patch. The instance template patch object is structured in the
        same way as a retrieved instance template and contains only the information to be
        updated.

        :param str id: The instance template identifier.
        :param str name: (optional) The unique user-defined name for this instance
               template.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceTemplate` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_instance_template')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance/templates/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_instances(self,
                       *,
                       start: str = None,
                       limit: int = None,
                       resource_group_id: str = None,
                       name: str = None,
                       vpc_id: str = None,
                       vpc_crn: str = None,
                       vpc_name: str = None,
                       **kwargs) -> DetailedResponse:
        """
        List all instances.

        This request lists all instances in the region.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param str name: (optional) Filters the collection to resources with the
               exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources in the
               VPC with the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources in the
               VPC with the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources in the
               VPC with the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_instances')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'name': name,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance(self, instance_prototype: 'InstancePrototype',
                        **kwargs) -> DetailedResponse:
        """
        Create an instance.

        This request provisions a new instance from an instance prototype object. The
        prototype object is structured in the same way as a retrieved instance, and
        contains the information necessary to provision the new instance. The instance is
        automatically started.

        :param InstancePrototype instance_prototype: The instance prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Instance` object
        """

        if instance_prototype is None:
            raise ValueError('instance_prototype must be provided')
        if isinstance(instance_prototype, InstancePrototype):
            instance_prototype = convert_model(instance_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_instance')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(instance_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified instance.

        This request deletes an instance. This operation cannot be reversed. Any floating
        IPs associated with the instance's network interfaces are implicitly
        disassociated. All flow log collectors with `auto_delete` set to `true` targeting
        the instance and/or the instance's network interfaces are automatically deleted.

        :param str id: The instance identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_instance')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instances/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve an instance.

        This request retrieves a single instance specified by the identifier in the URL.

        :param str id: The instance identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Instance` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_instance')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance(self,
                        id: str,
                        *,
                        name: str = None,
                        **kwargs) -> DetailedResponse:
        """
        Update specified instance.

        This request updates an instance with the information in a provided instance
        patch. The instance patch object is structured in the same way as a retrieved
        instance and contains only the information to be updated.

        :param str id: The instance identifier.
        :param str name: (optional) The user-defined name for this virtual server
               instance (and default system hostname).
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Instance` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_instance')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def get_instance_initialization(self, id: str,
                                    **kwargs) -> DetailedResponse:
        """
        Retrieve configuration used to initialize the instance.

        This request retrieves configuration variables used to initialize the instance,
        such as SSH keys and the Windows administrator password.

        :param str id: The instance identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceInitialization` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_instance_initialization')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/initialization'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_action(self,
                               instance_id: str,
                               type: str,
                               *,
                               force: bool = None,
                               **kwargs) -> DetailedResponse:
        """
        Create an instance action.

        This request creates a new action which will be queued up to run as soon as any
        pending or running actions have completed.

        :param str instance_id: The instance identifier.
        :param str type: The type of action.
        :param bool force: (optional) If set to true, the action will be forced
               immediately, and all queued actions deleted. Ignored for the start action.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceAction` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if type is None:
            raise ValueError('type must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_instance_action')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'type': type, 'force': force}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/actions'.format(
            *self.encode_path_vars(instance_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_instance_network_interfaces(self, instance_id: str,
                                         **kwargs) -> DetailedResponse:
        """
        List all network interfaces on an instance.

        This request lists all network interfaces on an instance. A network interface is
        an abstract representation of a network interface card and connects an instance to
        a subnet. While each network interface can attach to only one subnet, multiple
        network interfaces can be created to attach to multiple subnets. Multiple
        interfaces may also attach to the same subnet.

        :param str instance_id: The instance identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterfaceUnpaginatedCollection` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_instance_network_interfaces')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces'.format(
            *self.encode_path_vars(instance_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_network_interface(
            self,
            instance_id: str,
            subnet: 'SubnetIdentity',
            *,
            name: str = None,
            primary_ipv4_address: str = None,
            security_groups: List['SecurityGroupIdentity'] = None,
            **kwargs) -> DetailedResponse:
        """
        Create a network interface.

        This request creates a new network interface from a network interface prototype
        object. The prototype object is structured in the same way as a retrieved network
        interface, and contains the information necessary to create the new network
        interface. Any subnet in the instance's VPC may be specified, even if it is
        already attached to another network interface. Addresses on the network interface
        must be within the specified subnet's CIDR blocks.

        :param str instance_id: The instance identifier.
        :param SubnetIdentity subnet: The associated subnet.
        :param str name: (optional) The user-defined name for this network
               interface. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str primary_ipv4_address: (optional) The primary IPv4 address. If
               specified, it must be an available address on the network interface's
               subnet. If unspecified, an available address on the subnet will be
               automatically selected.
        :param List[SecurityGroupIdentity] security_groups: (optional) Collection
               of security groups.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterface` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if subnet is None:
            raise ValueError('subnet must be provided')
        subnet = convert_model(subnet)
        if security_groups is not None:
            security_groups = [convert_model(x) for x in security_groups]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_instance_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'subnet': subnet,
            'name': name,
            'primary_ipv4_address': primary_ipv4_address,
            'security_groups': security_groups
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces'.format(
            *self.encode_path_vars(instance_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_network_interface(self, instance_id: str, id: str,
                                          **kwargs) -> DetailedResponse:
        """
        Delete specified network interface.

        This request deletes a network interface. This operation cannot be reversed. Any
        floating IPs associated with the network interface are implicitly disassociated.
        All flow log collectors with `auto_delete` set to `true` targeting the network
        interface are automatically deleted. The primary network interface is not allowed
        to be deleted.

        :param str instance_id: The instance identifier.
        :param str id: The network interface identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instances/{0}/network_interfaces/{1}'.format(
            *self.encode_path_vars(instance_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_network_interface(self, instance_id: str, id: str,
                                       **kwargs) -> DetailedResponse:
        """
        Retrieve specified network interface.

        This request retrieves a single network interface specified by the identifier in
        the URL.

        :param str instance_id: The instance identifier.
        :param str id: The network interface identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterface` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_instance_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces/{1}'.format(
            *self.encode_path_vars(instance_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_network_interface(self,
                                          instance_id: str,
                                          id: str,
                                          *,
                                          name: str = None,
                                          **kwargs) -> DetailedResponse:
        """
        Update a network interface.

        This request updates a network interface with the information in a provided
        network interface patch. The network interface patch object is structured in the
        same way as a retrieved network interface and can contain an updated name and/or
        port speed.

        :param str instance_id: The instance identifier.
        :param str id: The network interface identifier.
        :param str name: (optional) The user-defined name for this network
               interface.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterface` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_instance_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces/{1}'.format(
            *self.encode_path_vars(instance_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_instance_network_interface_floating_ips(
            self, instance_id: str, network_interface_id: str,
            **kwargs) -> DetailedResponse:
        """
        List all floating IPs associated with a network interface.

        This request lists all floating IPs associated with a network interface.

        :param str instance_id: The instance identifier.
        :param str network_interface_id: The network interface identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIPUnpaginatedCollection` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if network_interface_id is None:
            raise ValueError('network_interface_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_instance_network_interface_floating_ips')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces/{1}/floating_ips'.format(
            *self.encode_path_vars(instance_id, network_interface_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def remove_instance_network_interface_floating_ip(
            self, instance_id: str, network_interface_id: str, id: str,
            **kwargs) -> DetailedResponse:
        """
        Disassociate specified floating IP.

        This request disassociates the specified floating IP from the specified network
        interface.

        :param str instance_id: The instance identifier.
        :param str network_interface_id: The network interface identifier.
        :param str id: The floating IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if network_interface_id is None:
            raise ValueError('network_interface_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_instance_network_interface_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instances/{0}/network_interfaces/{1}/floating_ips/{2}'.format(
            *self.encode_path_vars(instance_id, network_interface_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_network_interface_floating_ip(
            self, instance_id: str, network_interface_id: str, id: str,
            **kwargs) -> DetailedResponse:
        """
        Retrieve associated floating IP.

        This request a retrieves a specified floating IP address if it is associated with
        the network interface and instance specified in the URL.

        :param str instance_id: The instance identifier.
        :param str network_interface_id: The network interface identifier.
        :param str id: The floating IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIP` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if network_interface_id is None:
            raise ValueError('network_interface_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_instance_network_interface_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces/{1}/floating_ips/{2}'.format(
            *self.encode_path_vars(instance_id, network_interface_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def add_instance_network_interface_floating_ip(
            self, instance_id: str, network_interface_id: str, id: str,
            **kwargs) -> DetailedResponse:
        """
        Associate a floating IP with a network interface.

        This request associates the specified floating IP with the specified network
        interface, replacing any existing association. For this request to succeed, the
        existing floating IP must not be required by another resource, such as a public
        gateway. A request body is not required, and if supplied, is ignored.

        :param str instance_id: The instance identifier.
        :param str network_interface_id: The network interface identifier.
        :param str id: The floating IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIP` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if network_interface_id is None:
            raise ValueError('network_interface_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_instance_network_interface_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/network_interfaces/{1}/floating_ips/{2}'.format(
            *self.encode_path_vars(instance_id, network_interface_id, id))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_instance_volume_attachments(self, instance_id: str,
                                         **kwargs) -> DetailedResponse:
        """
        List all volumes attached to an instance.

        This request lists all volume attachments for an instance. A volume attachment
        connects a volume to an instance. Each instance may have many volume attachments
        but each volume attachment connects exactly one instance to exactly one volume.

        :param str instance_id: The instance identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeAttachmentCollection` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_instance_volume_attachments')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/volume_attachments'.format(
            *self.encode_path_vars(instance_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_volume_attachment(
            self,
            instance_id: str,
            volume: 'VolumeIdentity',
            *,
            name: str = None,
            delete_volume_on_instance_delete: bool = None,
            **kwargs) -> DetailedResponse:
        """
        Create a volume attachment, connecting a volume to an instance.

        This request creates a new volume attachment from a volume attachment prototype
        object. The prototype object is structured in the same way as a retrieved volume
        attachment, and contains the information necessary to create the new volume
        attachment. The creation of a new volume attachment connects a volume to an
        instance.

        :param str instance_id: The instance identifier.
        :param VolumeIdentity volume: The identity of the volume to attach to the
               instance.
        :param str name: (optional) The user-defined name for this volume
               attachment. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeAttachment` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if volume is None:
            raise ValueError('volume must be provided')
        volume = convert_model(volume)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_instance_volume_attachment')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'volume': volume,
            'name': name,
            'delete_volume_on_instance_delete': delete_volume_on_instance_delete
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/volume_attachments'.format(
            *self.encode_path_vars(instance_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_volume_attachment(self, instance_id: str, id: str,
                                          **kwargs) -> DetailedResponse:
        """
        Delete a volume attachment, detaching a volume from an instance.

        This request deletes a volume attachment. The deletion of a volume attachment
        detaches a volume from an instance.

        :param str instance_id: The instance identifier.
        :param str id: The volume attachment identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_volume_attachment')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instances/{0}/volume_attachments/{1}'.format(
            *self.encode_path_vars(instance_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_volume_attachment(self, instance_id: str, id: str,
                                       **kwargs) -> DetailedResponse:
        """
        Retrieve specified volume attachment.

        This request retrieves a single volume attachment specified by the identifier in
        the URL.

        :param str instance_id: The instance identifier.
        :param str id: The volume attachment identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeAttachment` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_instance_volume_attachment')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/volume_attachments/{1}'.format(
            *self.encode_path_vars(instance_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_volume_attachment(
            self,
            instance_id: str,
            id: str,
            *,
            name: str = None,
            delete_volume_on_instance_delete: bool = None,
            **kwargs) -> DetailedResponse:
        """
        Update a volume attachment.

        This request updates a volume attachment with the information in a provided volume
        attachment patch. The volume attachment patch object is structured in the same way
        as a retrieved volume attachment and can contain an updated name.

        :param str instance_id: The instance identifier.
        :param str id: The volume attachment identifier.
        :param str name: (optional) The user-defined name for this volume
               attachment.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeAttachment` object
        """

        if instance_id is None:
            raise ValueError('instance_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_instance_volume_attachment')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'delete_volume_on_instance_delete': delete_volume_on_instance_delete
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instances/{0}/volume_attachments/{1}'.format(
            *self.encode_path_vars(instance_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Instance groups
    #########################

    def list_instance_groups(self,
                             *,
                             start: str = None,
                             limit: int = None,
                             **kwargs) -> DetailedResponse:
        """
        List all instance groups.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_instance_groups')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_group(
            self,
            instance_template: 'InstanceTemplateIdentity',
            subnets: List['SubnetIdentity'],
            *,
            name: str = None,
            membership_count: int = None,
            application_port: int = None,
            load_balancer: 'LoadBalancerIdentity' = None,
            load_balancer_pool: 'LoadBalancerPoolIdentity' = None,
            resource_group: 'ResourceGroupIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Create an instance group.

        This request creates a new instance group.

        :param InstanceTemplateIdentity instance_template: Instance template to use
               when creating new instances.
        :param List[SubnetIdentity] subnets: Array of identities to subnets to use
               when creating new instances.
        :param str name: (optional) The user-defined name for this instance group.
        :param int membership_count: (optional) The number of instances in the
               instance group.
        :param int application_port: (optional) Required if specifying a load
               balancer pool only. Used by the instance group when scaling up instances to
               supply the port for the load balancer pool member.
        :param LoadBalancerIdentity load_balancer: (optional) The load balancer
               that the load balancer pool used by this group
               is in. Must be supplied when using a load balancer pool.
        :param LoadBalancerPoolIdentity load_balancer_pool: (optional) When
               specified, the load balancer pool will be managed by this
               group. Instances created by this group will have a new load
               balancer pool member in that pool created. Must be used with
               `application_port`.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroup` object
        """

        if instance_template is None:
            raise ValueError('instance_template must be provided')
        if subnets is None:
            raise ValueError('subnets must be provided')
        instance_template = convert_model(instance_template)
        subnets = [convert_model(x) for x in subnets]
        if load_balancer is not None:
            load_balancer = convert_model(load_balancer)
        if load_balancer_pool is not None:
            load_balancer_pool = convert_model(load_balancer_pool)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_instance_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'instance_template': instance_template,
            'subnets': subnets,
            'name': name,
            'membership_count': membership_count,
            'application_port': application_port,
            'load_balancer': load_balancer,
            'load_balancer_pool': load_balancer_pool,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_group(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified instance group.

        This request deletes an instance group. This operation cannot be reversed. Any
        instances associated with the group will be deleted.

        :param str id: The instance group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_instance_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance_groups/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_group(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified instance group.

        This request retrieves a single instance group specified by identifier in the URL.

        :param str id: The instance group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroup` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_instance_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_group(
            self,
            id: str,
            *,
            name: str = None,
            membership_count: int = None,
            instance_template: 'InstanceTemplateIdentity' = None,
            subnets: List['SubnetIdentity'] = None,
            application_port: int = None,
            load_balancer: 'LoadBalancerIdentity' = None,
            load_balancer_pool: 'LoadBalancerPoolIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Update specified instance group.

        This request updates an instance group with the information provided instance
        group patch. The instance group patch object is structured in the same way as a
        retrieved instance group and contains only the information to be updated.

        :param str id: The instance group identifier.
        :param str name: (optional) The user-defined name for this instance group.
        :param int membership_count: (optional) The number of instances in the
               instance group.
        :param InstanceTemplateIdentity instance_template: (optional) Instance
               template to use when creating new instances.
        :param List[SubnetIdentity] subnets: (optional) Array of identities to
               subnets to use when creating new instances.
        :param int application_port: (optional) Required if specifying a load
               balancer pool only. Used by the instance group when scaling up instances to
               supply the port for the load balancer pool member.
        :param LoadBalancerIdentity load_balancer: (optional) The load balancer
               that the load balancer pool used by this group
               is in. Must be supplied when using a load balancer pool.
        :param LoadBalancerPoolIdentity load_balancer_pool: (optional) When
               specified, the load balancer pool will be managed by this
               group. Instances created by this group will have a new load
               balancer pool member in that pool created. Must be used with
               `application_port`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroup` object
        """

        if id is None:
            raise ValueError('id must be provided')
        if instance_template is not None:
            instance_template = convert_model(instance_template)
        if subnets is not None:
            subnets = [convert_model(x) for x in subnets]
        if load_balancer is not None:
            load_balancer = convert_model(load_balancer)
        if load_balancer_pool is not None:
            load_balancer_pool = convert_model(load_balancer_pool)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_instance_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'membership_count': membership_count,
            'instance_template': instance_template,
            'subnets': subnets,
            'application_port': application_port,
            'load_balancer': load_balancer,
            'load_balancer_pool': load_balancer_pool
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_group_load_balancer(self, instance_group_id: str,
                                            **kwargs) -> DetailedResponse:
        """
        Delete specified instance group load balancer.

        This request unbinds the instance group from the load balancer pool, and deletes
        the load balancer pool members.

        :param str instance_group_id: The instance group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_group_load_balancer')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance_groups/{0}/load_balancer'.format(
            *self.encode_path_vars(instance_group_id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_instance_group_managers(self, instance_group_id: str,
                                     **kwargs) -> DetailedResponse:
        """
        List all managers for an instance group.

        This request retrieves instance group managers.

        :param str instance_group_id: The instance group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManagerCollection` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_instance_group_managers')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers'.format(
            *self.encode_path_vars(instance_group_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_group_manager(
            self, instance_group_id: str,
            instance_group_manager_prototype: 'InstanceGroupManagerPrototype',
            **kwargs) -> DetailedResponse:
        """
        Create an instance group manager.

        This request creates a new instance group manager.

        :param str instance_group_id: The instance group identifier.
        :param InstanceGroupManagerPrototype instance_group_manager_prototype: The
               instance group manager prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManager` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if instance_group_manager_prototype is None:
            raise ValueError(
                'instance_group_manager_prototype must be provided')
        if isinstance(instance_group_manager_prototype,
                      InstanceGroupManagerPrototype):
            instance_group_manager_prototype = convert_model(
                instance_group_manager_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_instance_group_manager')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(instance_group_manager_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers'.format(
            *self.encode_path_vars(instance_group_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_group_manager(self, instance_group_id: str, id: str,
                                      **kwargs) -> DetailedResponse:
        """
        Delete specified instance group manager.

        This request deletes an instance group manager. This operation cannot be reversed.

        :param str instance_group_id: The instance group identifier.
        :param str id: The instance group manager identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_group_manager')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance_groups/{0}/managers/{1}'.format(
            *self.encode_path_vars(instance_group_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_group_manager(self, instance_group_id: str, id: str,
                                   **kwargs) -> DetailedResponse:
        """
        Retrieve specified instance group.

        This request retrieves a single instance group manager specified by identifier in
        the URL.

        :param str instance_group_id: The instance group identifier.
        :param str id: The instance group manager identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManager` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_instance_group_manager')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers/{1}'.format(
            *self.encode_path_vars(instance_group_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_group_manager(self,
                                      instance_group_id: str,
                                      id: str,
                                      *,
                                      name: str = None,
                                      management_enabled: bool = None,
                                      aggregation_window: int = None,
                                      cooldown: int = None,
                                      max_membership_count: int = None,
                                      min_membership_count: int = None,
                                      **kwargs) -> DetailedResponse:
        """
        Update specified instance group manager.

        This request updates an instance group manager with the information provided
        instance group manager patch.

        :param str instance_group_id: The instance group identifier.
        :param str id: The instance group manager identifier.
        :param str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within the instance group.
        :param bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        :param int aggregation_window: (optional) The time window in seconds to
               aggregate metrics prior to evaluation.
        :param int cooldown: (optional) The duration of time in seconds to pause
               further scale actions after scaling has taken place.
        :param int max_membership_count: (optional) The maximum number of members
               in a managed instance group.
        :param int min_membership_count: (optional) The minimum number of members
               in a managed instance group.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManager` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_instance_group_manager')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'management_enabled': management_enabled,
            'aggregation_window': aggregation_window,
            'cooldown': cooldown,
            'max_membership_count': max_membership_count,
            'min_membership_count': min_membership_count
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers/{1}'.format(
            *self.encode_path_vars(instance_group_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_instance_group_manager_policies(self, instance_group_id: str,
                                             instance_group_manager_id: str,
                                             **kwargs) -> DetailedResponse:
        """
        List all policies for an instance group manager.

        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManagerPolicyCollection` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if instance_group_manager_id is None:
            raise ValueError('instance_group_manager_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_instance_group_manager_policies')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers/{1}/policies'.format(
            *self.encode_path_vars(instance_group_id,
                                   instance_group_manager_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_group_manager_policy(
            self, instance_group_id: str, instance_group_manager_id: str,
            instance_group_manager_policy_prototype:
        'InstanceGroupManagerPolicyPrototype', **kwargs) -> DetailedResponse:
        """
        Create an instance group manager policy.

        This request creates a new instance group manager policy.

        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param InstanceGroupManagerPolicyPrototype
               instance_group_manager_policy_prototype: The instance group manager policy
               prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManagerPolicy` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if instance_group_manager_id is None:
            raise ValueError('instance_group_manager_id must be provided')
        if instance_group_manager_policy_prototype is None:
            raise ValueError(
                'instance_group_manager_policy_prototype must be provided')
        if isinstance(instance_group_manager_policy_prototype,
                      InstanceGroupManagerPolicyPrototype):
            instance_group_manager_policy_prototype = convert_model(
                instance_group_manager_policy_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_instance_group_manager_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(instance_group_manager_policy_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers/{1}/policies'.format(
            *self.encode_path_vars(instance_group_id,
                                   instance_group_manager_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_group_manager_policy(self, instance_group_id: str,
                                             instance_group_manager_id: str,
                                             id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Delete specified instance group manager policy.

        This request deletes an instance group manager policy. This operation cannot be
        reversed.

        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param str id: The instance group manager policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if instance_group_manager_id is None:
            raise ValueError('instance_group_manager_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_group_manager_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance_groups/{0}/managers/{1}/policies/{2}'.format(
            *self.encode_path_vars(instance_group_id, instance_group_manager_id,
                                   id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_group_manager_policy(self, instance_group_id: str,
                                          instance_group_manager_id: str,
                                          id: str,
                                          **kwargs) -> DetailedResponse:
        """
        Retrieve specified instance group manager policy.

        This request retrieves a single instance group manager policy specified by
        identifier in the URL.

        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param str id: The instance group manager policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManagerPolicy` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if instance_group_manager_id is None:
            raise ValueError('instance_group_manager_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_instance_group_manager_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers/{1}/policies/{2}'.format(
            *self.encode_path_vars(instance_group_id, instance_group_manager_id,
                                   id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_group_manager_policy(self,
                                             instance_group_id: str,
                                             instance_group_manager_id: str,
                                             id: str,
                                             *,
                                             name: str = None,
                                             metric_type: str = None,
                                             metric_value: int = None,
                                             **kwargs) -> DetailedResponse:
        """
        Update specified instance group manager policy.

        This request updates an instance group manager policy.

        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param str id: The instance group manager policy identifier.
        :param str name: (optional) The user-defined name for this instance group
               manager policy. Names must be unique within the instance group manager.
        :param str metric_type: (optional) The type of metric to be evaluated.
        :param int metric_value: (optional) The metric value to be evaluated.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupManagerPolicy` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if instance_group_manager_id is None:
            raise ValueError('instance_group_manager_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_instance_group_manager_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'metric_type': metric_type,
            'metric_value': metric_value
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/managers/{1}/policies/{2}'.format(
            *self.encode_path_vars(instance_group_id, instance_group_manager_id,
                                   id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_instance_group_memberships(self, instance_group_id: str,
                                          **kwargs) -> DetailedResponse:
        """
        Delete all memberships from the instance group.

        This request deletes all memberships of an instance group. This operation cannot
        be reversed. reversed. Any memberships that have
        `delete_instance_on_membership_delete` set to `true` will also have their
        instances deleted.

        :param str instance_group_id: The instance group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_group_memberships')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance_groups/{0}/memberships'.format(
            *self.encode_path_vars(instance_group_id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_instance_group_memberships(self, instance_group_id: str,
                                        **kwargs) -> DetailedResponse:
        """
        List all memberships for the instance group.

        :param str instance_group_id: The instance group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupMembershipCollection` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_instance_group_memberships')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/memberships'.format(
            *self.encode_path_vars(instance_group_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def delete_instance_group_membership(self, instance_group_id: str, id: str,
                                         **kwargs) -> DetailedResponse:
        """
        Delete specified instance group membership.

        This request deletes a memberships of an instance group. This operation cannot be
        reversed. reversed. If the membership has `delete_instance_on_membership_delete`
        set to `true`, the instance will also be deleted.

        :param str instance_group_id: The instance group identifier.
        :param str id: The instance group membership identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_group_membership')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/instance_groups/{0}/memberships/{1}'.format(
            *self.encode_path_vars(instance_group_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_instance_group_membership(self, instance_group_id: str, id: str,
                                      **kwargs) -> DetailedResponse:
        """
        Retrieve specified instance group membership.

        This request retrieves a single instance group membership specified by identifier
        in the URL.

        :param str instance_group_id: The instance group identifier.
        :param str id: The instance group membership identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupMembership` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_instance_group_membership')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/memberships/{1}'.format(
            *self.encode_path_vars(instance_group_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_group_membership(self,
                                         instance_group_id: str,
                                         id: str,
                                         *,
                                         name: str = None,
                                         **kwargs) -> DetailedResponse:
        """
        Update specified instance group membership.

        This request updates an instance group membership with the information provided
        instance group membership patch.

        :param str instance_group_id: The instance group identifier.
        :param str id: The instance group membership identifier.
        :param str name: (optional) The user-defined name for this instance group
               membership. Names must be unique within the instance group.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroupMembership` object
        """

        if instance_group_id is None:
            raise ValueError('instance_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_instance_group_membership')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/instance_groups/{0}/memberships/{1}'.format(
            *self.encode_path_vars(instance_group_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Volumes
    #########################

    def list_volume_profiles(self,
                             *,
                             start: str = None,
                             limit: int = None,
                             **kwargs) -> DetailedResponse:
        """
        List all volume profiles.

        This request lists all volume profiles available in the region. A volume profile
        specifies the performance characteristics and pricing model for a volume.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeProfileCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_volume_profiles')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/volume/profiles'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_volume_profile(self, name: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified volume profile.

        This request retrieves a single volume profile specified by the name in the URL.

        :param str name: The volume profile name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeProfile` object
        """

        if name is None:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_volume_profile')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/volume/profiles/{0}'.format(*self.encode_path_vars(name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_volumes(self,
                     *,
                     start: str = None,
                     limit: int = None,
                     name: str = None,
                     zone_name: str = None,
                     **kwargs) -> DetailedResponse:
        """
        List all volumes.

        This request lists all volumes in the region. Volumes are network-connected block
        storage devices that may be attached to one or more instances in the same region.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str name: (optional) Filters the collection to resources with the
               exact specified name.
        :param str zone_name: (optional) Filters the collection to resources in the
               zone with the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VolumeCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_volumes')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'name': name,
            'zone.name': zone_name
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/volumes'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_volume(self, volume_prototype: 'VolumePrototype',
                      **kwargs) -> DetailedResponse:
        """
        Create a volume.

        This request creates a new volume from a volume prototype object. The prototype
        object is structured in the same way as a retrieved volume, and contains the
        information necessary to create the new volume.

        :param VolumePrototype volume_prototype: The volume prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Volume` object
        """

        if volume_prototype is None:
            raise ValueError('volume_prototype must be provided')
        if isinstance(volume_prototype, VolumePrototype):
            volume_prototype = convert_model(volume_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_volume')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(volume_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/volumes'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_volume(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified volume.

        This request deletes a volume. This operation cannot be reversed. For this request
        to succeed, the volume must not be attached to any instances.

        :param str id: The volume identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_volume')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/volumes/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_volume(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified volume.

        This request retrieves a single volume specified by the identifier in the URL.

        :param str id: The volume identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Volume` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_volume')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/volumes/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_volume(self,
                      id: str,
                      *,
                      name: str = None,
                      **kwargs) -> DetailedResponse:
        """
        Update specified volume.

        This request updates a volume with the information in a provided volume patch. The
        volume patch object is structured in the same way as a retrieved volume and
        contains only the information to be updated.

        :param str id: The volume identifier.
        :param str name: (optional) The unique user-defined name for this volume.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Volume` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_volume')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/volumes/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Geography
    #########################

    def list_regions(self, **kwargs) -> DetailedResponse:
        """
        List all regions.

        This request lists all regions. Each region is a separate geographic area that
        contains multiple isolated zones. Resources can be provisioned into a one or more
        zones in a region. Each zone is isolated, but connected to other zones in the same
        region with low-latency and high-bandwidth links. Regions represent the top-level
        of fault isolation available. Resources deployed within a single region also
        benefit from the low latency afforded by geographic proximity.

        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RegionCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_regions')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/regions'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_region(self, name: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a region.

        This request retrieves a single region specified by the name in the URL.

        :param str name: The region name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Region` object
        """

        if name is None:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_region')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/regions/{0}'.format(*self.encode_path_vars(name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_region_zones(self, region_name: str, **kwargs) -> DetailedResponse:
        """
        List all zones in a region.

        This request lists all zones in a region. Zones represent logically-isolated data
        centers with high-bandwidth and low-latency interconnects to other zones in the
        same region. Faults in a zone do not affect other zones.

        :param str region_name: The region name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ZoneCollection` object
        """

        if region_name is None:
            raise ValueError('region_name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_region_zones')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/regions/{0}/zones'.format(*self.encode_path_vars(region_name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_region_zone(self, region_name: str, zone_name: str,
                        **kwargs) -> DetailedResponse:
        """
        Retrieve a zone.

        This request retrieves a single zone specified by the region and zone names in the
        URL.

        :param str region_name: The region name.
        :param str zone_name: The zone name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Zone` object
        """

        if region_name is None:
            raise ValueError('region_name must be provided')
        if zone_name is None:
            raise ValueError('zone_name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_region_zone')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/regions/{0}/zones/{1}'.format(
            *self.encode_path_vars(region_name, zone_name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    #########################
    # Public gateways
    #########################

    def list_public_gateways(self,
                             *,
                             start: str = None,
                             limit: int = None,
                             resource_group_id: str = None,
                             **kwargs) -> DetailedResponse:
        """
        List all public gateways.

        This request lists all public gateways. A public gateway is a virtual network
        device associated with a VPC, which allows access to the Internet. A public
        gateway resides in a zone and can be connected to subnets in the same zone only.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGatewayCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_public_gateways')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/public_gateways'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_public_gateway(
            self,
            vpc: 'VPCIdentity',
            zone: 'ZoneIdentity',
            *,
            name: str = None,
            floating_ip: 'PublicGatewayPrototypeFloatingIp' = None,
            resource_group: 'ResourceGroupIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Create a public gateway.

        This request creates a new public gateway from a public gateway prototype object.
        For this to succeed, the VPC must not already have a public gateway in the
        specified zone.
        If a floating IP is provided, it must be unbound. If a floating IP is not
        provided, one will be created and bound to the public gateway. Once a public
        gateway has been created, its floating IP cannot be unbound. A public gateway must
        be explicitly attached to each subnet it will provide connectivity for.

        :param VPCIdentity vpc: The VPC this public gateway will serve.
        :param ZoneIdentity zone: The zone where this public gateway will be
               created.
        :param str name: (optional) The user-defined name for this public gateway.
               Names must be unique within the VPC the public gateway resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param PublicGatewayPrototypeFloatingIp floating_ip: (optional)
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGateway` object
        """

        if vpc is None:
            raise ValueError('vpc must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        vpc = convert_model(vpc)
        zone = convert_model(zone)
        if floating_ip is not None:
            floating_ip = convert_model(floating_ip)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'vpc': vpc,
            'zone': zone,
            'name': name,
            'floating_ip': floating_ip,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/public_gateways'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_public_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified public gateway.

        This request deletes a public gateway. This operation cannot be reversed. For this
        request to succeed, the public gateway must not be attached to any subnets. The
        public gateway's floating IP will be automatically unbound. If the floating IP was
        created when the public gateway was created, it will be deleted.

        :param str id: The public gateway identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/public_gateways/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_public_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified public gateway.

        This request retrieves a single public gateway specified by the identifier in the
        URL.

        :param str id: The public gateway identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGateway` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/public_gateways/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_public_gateway(self,
                              id: str,
                              *,
                              name: str = None,
                              **kwargs) -> DetailedResponse:
        """
        Update a public gateway's name.

        This request updates a public gateway's name.

        :param str id: The public gateway identifier.
        :param str name: (optional) The user-defined name for this public gateway.
               Names must be unique within the VPC the public gateway resides in.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGateway` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_public_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/public_gateways/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Floating IPs
    #########################

    def list_floating_ips(self,
                          *,
                          start: str = None,
                          limit: int = None,
                          resource_group_id: str = None,
                          **kwargs) -> DetailedResponse:
        """
        List all floating IPs.

        This request retrieves all floating IPs in the region. Floating IPs allow inbound
        and outbound traffic from the Internet to an instance.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIPCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_floating_ips')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/floating_ips'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_floating_ip(self, floating_ip_prototype: 'FloatingIPPrototype',
                           **kwargs) -> DetailedResponse:
        """
        Reserve a floating IP.

        This request reserves a new floating IP.

        :param FloatingIPPrototype floating_ip_prototype: The floating IP prototype
               object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIP` object
        """

        if floating_ip_prototype is None:
            raise ValueError('floating_ip_prototype must be provided')
        if isinstance(floating_ip_prototype, FloatingIPPrototype):
            floating_ip_prototype = convert_model(floating_ip_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(floating_ip_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/floating_ips'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_floating_ip(self, id: str, **kwargs) -> DetailedResponse:
        """
        Release the specified floating IP.

        This request disassociates (if associated) and releases a floating IP. This
        operation cannot be reversed. For this request to succeed, the floating IP must
        not be required by another resource, such as a public gateway.

        :param str id: The floating IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/floating_ips/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_floating_ip(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified floating IP.

        This request retrieves a single floating IP specified by the identifier in the
        URL.

        :param str id: The floating IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIP` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/floating_ips/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_floating_ip(
            self,
            id: str,
            *,
            name: str = None,
            target: 'FloatingIPPatchTargetNetworkInterfaceIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Update the specified floating IP.

        This request updates a floating IP's name and/or target.

        :param str id: The floating IP identifier.
        :param str name: (optional) The unique user-defined name for this floating
               IP.
        :param FloatingIPPatchTargetNetworkInterfaceIdentity target: (optional) A
               new network interface to bind this floating IP to, replacing any existing
               binding.
               For this request to succeed, the existing floating IP must not be required
               by another
               resource, such as a public gateway.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIP` object
        """

        if id is None:
            raise ValueError('id must be provided')
        if target is not None:
            target = convert_model(target)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_floating_ip')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name, 'target': target}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/floating_ips/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Network ACLs
    #########################

    def list_network_acls(self,
                          *,
                          start: str = None,
                          limit: int = None,
                          resource_group_id: str = None,
                          **kwargs) -> DetailedResponse:
        """
        List all network ACLs.

        This request lists all network ACLs in the region. A network ACL defines a set of
        packet filtering (5-tuple) rules for all traffic in and out of a subnet. Both
        allow and deny rules can be defined, and rules are stateless such that reverse
        traffic in response to allowed traffic is not automatically permitted.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACLCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_network_acls')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_network_acl(self,
                           *,
                           network_acl_prototype: 'NetworkACLPrototype' = None,
                           **kwargs) -> DetailedResponse:
        """
        Create a network ACL.

        This request creates a new network ACL from a network ACL prototype object. The
        prototype object is structured in the same way as a retrieved network ACL, and
        contains the information necessary to create the new network ACL.

        :param NetworkACLPrototype network_acl_prototype: (optional) The network
               ACL prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACL` object
        """

        if network_acl_prototype is not None and isinstance(
                network_acl_prototype, NetworkACLPrototype):
            network_acl_prototype = convert_model(network_acl_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(network_acl_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_network_acl(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete specified network ACL.

        This request deletes a network ACL. This operation cannot be reversed. For this
        request to succeed, the network ACL must not be the default network ACL for any
        VPCs, and the network ACL must not be attached to any subnets.

        :param str id: The network ACL identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/network_acls/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_network_acl(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve specified network ACL.

        This request retrieves a single network ACL specified by the identifier in the
        URL.

        :param str id: The network ACL identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACL` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_network_acl(self,
                           id: str,
                           *,
                           name: str = None,
                           **kwargs) -> DetailedResponse:
        """
        Update a network ACL.

        This request updates a network ACL's name.

        :param str id: The network ACL identifier.
        :param str name: (optional) The user-defined name for this network ACL.
               Names must be unique within the VPC the Network ACL resides in.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACL` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_network_acl')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_network_acl_rules(self,
                               network_acl_id: str,
                               *,
                               start: str = None,
                               limit: int = None,
                               direction: str = None,
                               **kwargs) -> DetailedResponse:
        """
        List all rules for a network ACL.

        This request lists all rules for a network ACL. These rules can allow or deny
        traffic between a source CIDR block and a destination CIDR block over a particular
        protocol and port range.

        :param str network_acl_id: The network ACL identifier.
        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str direction: (optional) Filters the collection to rules with the
               specified direction.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACLRuleCollection` object
        """

        if network_acl_id is None:
            raise ValueError('network_acl_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_network_acl_rules')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'direction': direction
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls/{0}/rules'.format(
            *self.encode_path_vars(network_acl_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_network_acl_rule(
            self, network_acl_id: str,
            network_acl_rule_prototype: 'NetworkACLRulePrototype',
            **kwargs) -> DetailedResponse:
        """
        Create a rule.

        This request creates a new rule from a network ACL rule prototype object. The
        prototype object is structured in the same way as a retrieved rule, and contains
        the information necessary to create the new rule.

        :param str network_acl_id: The network ACL identifier.
        :param NetworkACLRulePrototype network_acl_rule_prototype: The network ACL
               rule prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACLRule` object
        """

        if network_acl_id is None:
            raise ValueError('network_acl_id must be provided')
        if network_acl_rule_prototype is None:
            raise ValueError('network_acl_rule_prototype must be provided')
        if isinstance(network_acl_rule_prototype, NetworkACLRulePrototype):
            network_acl_rule_prototype = convert_model(
                network_acl_rule_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_network_acl_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(network_acl_rule_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls/{0}/rules'.format(
            *self.encode_path_vars(network_acl_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_network_acl_rule(self, network_acl_id: str, id: str,
                                **kwargs) -> DetailedResponse:
        """
        Delete specified rule.

        This request deletes a rule. This operation cannot be reversed.

        :param str network_acl_id: The network ACL identifier.
        :param str id: The rule identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if network_acl_id is None:
            raise ValueError('network_acl_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_network_acl_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/network_acls/{0}/rules/{1}'.format(
            *self.encode_path_vars(network_acl_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_network_acl_rule(self, network_acl_id: str, id: str,
                             **kwargs) -> DetailedResponse:
        """
        Retrieve specified rule.

        This request retrieves a single rule specified by the identifier in the URL.

        :param str network_acl_id: The network ACL identifier.
        :param str id: The rule identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACLRule` object
        """

        if network_acl_id is None:
            raise ValueError('network_acl_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_network_acl_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls/{0}/rules/{1}'.format(
            *self.encode_path_vars(network_acl_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_network_acl_rule(self,
                                network_acl_id: str,
                                id: str,
                                *,
                                name: str = None,
                                action: str = None,
                                destination: str = None,
                                direction: str = None,
                                source: str = None,
                                destination_port_max: int = None,
                                destination_port_min: int = None,
                                source_port_max: int = None,
                                source_port_min: int = None,
                                code: int = None,
                                type: int = None,
                                before: 'NetworkACLRuleIdentity' = None,
                                **kwargs) -> DetailedResponse:
        """
        Update a rule.

        This request updates a rule with the information in a provided rule patch. The
        rule patch object contains only the information to be updated. The request will
        fail if the information is not applicable to the rule's protocol.

        :param str network_acl_id: The network ACL identifier.
        :param str id: The rule identifier.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in.
        :param str action: (optional) Whether to allow or deny matching traffic.
        :param str destination: (optional) The destination IP address or CIDR
               block. The CIDR block `0.0.0.0/0` applies to all addresses.
        :param str direction: (optional) Whether the traffic to be matched is
               `inbound` or `outbound`.
        :param str source: (optional) The source IP address or CIDR block.  The
               CIDR block `0.0.0.0/0` applies to all addresses.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        :param int code: (optional) The ICMP traffic code to allow.
        :param int type: (optional) The ICMP traffic type to allow.
        :param NetworkACLRuleIdentity before: (optional) The rule to move this rule
               immediately before. Specify `null` to move this rule after
               all existing rules.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACLRule` object
        """

        if network_acl_id is None:
            raise ValueError('network_acl_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if before is not None:
            before = convert_model(before)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_network_acl_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'action': action,
            'destination': destination,
            'direction': direction,
            'source': source,
            'destination_port_max': destination_port_max,
            'destination_port_min': destination_port_min,
            'source_port_max': source_port_max,
            'source_port_min': source_port_min,
            'code': code,
            'type': type,
            'before': before
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/network_acls/{0}/rules/{1}'.format(
            *self.encode_path_vars(network_acl_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Security groups
    #########################

    def list_security_groups(self,
                             *,
                             start: str = None,
                             limit: int = None,
                             resource_group_id: str = None,
                             vpc_id: str = None,
                             vpc_crn: str = None,
                             vpc_name: str = None,
                             **kwargs) -> DetailedResponse:
        """
        List all security groups.

        This request lists all existing security groups. Security groups provide a
        convenient way to apply IP filtering rules to instances in the associated VPC.
        With security groups, all traffic is denied by default, and rules added to
        security groups define which traffic the security group permits. Security group
        rules are stateful such that reverse traffic in response to allowed traffic is
        automatically permitted.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param str vpc_id: (optional) Filters the collection to resources in the
               VPC with the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources in the
               VPC with the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources in the
               VPC with the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_security_groups')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_security_group(self,
                              vpc: 'VPCIdentity',
                              *,
                              name: str = None,
                              resource_group: 'ResourceGroupIdentity' = None,
                              rules: List['SecurityGroupRulePrototype'] = None,
                              **kwargs) -> DetailedResponse:
        """
        Create a security group.

        This request creates a new security group from a security group prototype object.
        The prototype object is structured in the same way as a retrieved security group,
        and contains the information necessary to create the new security group. If
        security group rules are included in the protoype object, those rules will be
        added to the security group. Each security group is scoped to one VPC. Only
        network interfaces on instances in that VPC can be added to the security group.

        :param VPCIdentity vpc: The VPC this security group is to be a part of.
        :param str name: (optional) The user-defined name for this security group.
               If unspecified, the name will be a hyphenated list of randomly-selected
               words. Names must be unique within the VPC the security group resides in.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param List[SecurityGroupRulePrototype] rules: (optional) Array of rule
               prototype objects for rules to be created for this security group. If
               unspecified, no rules will be created, resulting in all traffic being
               denied.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroup` object
        """

        if vpc is None:
            raise ValueError('vpc must be provided')
        vpc = convert_model(vpc)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if rules is not None:
            rules = [convert_model(x) for x in rules]
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_security_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'vpc': vpc,
            'name': name,
            'resource_group': resource_group,
            'rules': rules
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_security_group(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete a security group.

        This request deletes a security group. A security group cannot be deleted if it is
        referenced by any network interfaces or other security group rules. Additionally,
        a VPC's default security group cannot be deleted. This operation cannot be
        reversed.

        :param str id: The security group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_security_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/security_groups/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_security_group(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a security group.

        This request retrieves a single security group specified by the identifier in the
        URL path.

        :param str id: The security group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroup` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_security_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_security_group(self,
                              id: str,
                              *,
                              name: str = None,
                              **kwargs) -> DetailedResponse:
        """
        Update a security group.

        This request updates a security group with the information provided in a security
        group patch object. The security group patch object is structured in the same way
        as a retrieved security group and contains only the information to be updated.

        :param str id: The security group identifier.
        :param str name: (optional) The user-defined name for this security group.
               Names must be unique within the VPC the security group resides in.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroup` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_security_group')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_security_group_network_interfaces(self,
                                               security_group_id: str,
                                               *,
                                               start: str = None,
                                               limit: int = None,
                                               **kwargs) -> DetailedResponse:
        """
        List a security group's network interfaces.

        This request lists all network interfaces associated with the security group, to
        which the rules in the security group are applied.

        :param str security_group_id: The security group identifier.
        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterfaceCollection` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_security_group_network_interfaces')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/network_interfaces'.format(
            *self.encode_path_vars(security_group_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def remove_security_group_network_interface(self, security_group_id: str,
                                                id: str,
                                                **kwargs) -> DetailedResponse:
        """
        Remove a network interface from a security group.

        This request removes a network interface from a security group. Security groups
        are stateful, so any changes to a network interface's security groups are applied
        to new connections. Existing connections are not affected. If the network
        interface being removed has no other security groups, it will be attached to the
        VPC's default security group.

        :param str security_group_id: The security group identifier.
        :param str id: The network interface identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_security_group_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/security_groups/{0}/network_interfaces/{1}'.format(
            *self.encode_path_vars(security_group_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_security_group_network_interface(self, security_group_id: str,
                                             id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Retrieve a network interface in a security group.

        This request retrieves a single network interface specified by the identifier in
        the URL path. The network interface must be an existing member of the security
        group.

        :param str security_group_id: The security group identifier.
        :param str id: The network interface identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterface` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_security_group_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/network_interfaces/{1}'.format(
            *self.encode_path_vars(security_group_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def add_security_group_network_interface(self, security_group_id: str,
                                             id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Add a network interface to a security group.

        This request adds an existing network interface to an existing security group.
        When a network interface is added to a security group, the security group rules
        are applied to the network interface. A request body is not required, and if
        supplied, is ignored.

        :param str security_group_id: The security group identifier.
        :param str id: The network interface identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkInterface` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_security_group_network_interface')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/network_interfaces/{1}'.format(
            *self.encode_path_vars(security_group_id, id))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_security_group_rules(self, security_group_id: str,
                                  **kwargs) -> DetailedResponse:
        """
        List all the rules of a security group.

        This request lists all the security group rules for a particular security group.
        These rules define what traffic the security group permits. Security group rules
        are stateful, such that reverse traffic in response to allowed traffic is
        automatically permitted.

        :param str security_group_id: The security group identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupRuleCollection` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_security_group_rules')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/rules'.format(
            *self.encode_path_vars(security_group_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_security_group_rule(
            self, security_group_id: str,
            security_group_rule_prototype: 'SecurityGroupRulePrototype',
            **kwargs) -> DetailedResponse:
        """
        Create a security group rule.

        This request creates a new security group rule from a security group rule
        prototype object. The prototype object is structured in the same way as a
        retrieved security group rule and contains the information necessary to create the
        rule. As part of creating a new rule in a security group, the rule is applied to
        all the networking interfaces in the security group. Rules specify which IP
        traffic a security group should allow. Security group rules are stateful, such
        that reverse traffic in response to allowed traffic is automatically permitted. A
        rule allowing inbound TCP traffic on port 80 also allows outbound TCP traffic on
        port 80 without the need for an additional rule.

        :param str security_group_id: The security group identifier.
        :param SecurityGroupRulePrototype security_group_rule_prototype: The
               properties of the security group rule to be created.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupRule` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if security_group_rule_prototype is None:
            raise ValueError('security_group_rule_prototype must be provided')
        if isinstance(security_group_rule_prototype,
                      SecurityGroupRulePrototype):
            security_group_rule_prototype = convert_model(
                security_group_rule_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_security_group_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = json.dumps(security_group_rule_prototype)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/rules'.format(
            *self.encode_path_vars(security_group_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_security_group_rule(self, security_group_id: str, id: str,
                                   **kwargs) -> DetailedResponse:
        """
        Delete a security group rule.

        This request deletes a security group rule. This operation cannot be reversed.
        Removing a security group rule will not end existing connections allowed by that
        rule.

        :param str security_group_id: The security group identifier.
        :param str id: The rule identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_security_group_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/security_groups/{0}/rules/{1}'.format(
            *self.encode_path_vars(security_group_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_security_group_rule(self, security_group_id: str, id: str,
                                **kwargs) -> DetailedResponse:
        """
        Retrieve a security group rule.

        This request retrieves a single security group rule specified by the identifier in
        the URL path.

        :param str security_group_id: The security group identifier.
        :param str id: The rule identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupRule` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_security_group_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/rules/{1}'.format(
            *self.encode_path_vars(security_group_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_security_group_rule(
            self,
            security_group_id: str,
            id: str,
            *,
            remote: 'SecurityGroupRulePatchRemote' = None,
            direction: str = None,
            ip_version: str = None,
            code: int = None,
            port_max: int = None,
            port_min: int = None,
            type: int = None,
            **kwargs) -> DetailedResponse:
        """
        Update a security group rule.

        This request updates a security group rule with the information in a provided rule
        patch object. The rule patch object contains only the information to be updated.
        The request will fail if the information is not applicable to the rule's protocol.

        :param str security_group_id: The security group identifier.
        :param str id: The rule identifier.
        :param SecurityGroupRulePatchRemote remote: (optional) The IP addresses or
               security groups from which this rule will allow traffic (or to
               which, for outbound rules). Can be specified as an IP address, a CIDR
               block, or a
               security group. A CIDR block of `0.0.0.0/0` will allow traffic from any
               source (or to
               any source, for outbound rules).
        :param str direction: (optional) The direction of traffic to enforce,
               either `inbound` or `outbound`.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param int code: (optional) The ICMP traffic code to allow.
        :param int port_max: (optional) The inclusive upper bound of TCP/UDP port
               range.
        :param int port_min: (optional) The inclusive lower bound of TCP/UDP port
               range.
        :param int type: (optional) The ICMP traffic type to allow.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupRule` object
        """

        if security_group_id is None:
            raise ValueError('security_group_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if remote is not None:
            remote = convert_model(remote)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_security_group_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'remote': remote,
            'direction': direction,
            'ip_version': ip_version,
            'code': code,
            'port_max': port_max,
            'port_min': port_min,
            'type': type
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/security_groups/{0}/rules/{1}'.format(
            *self.encode_path_vars(security_group_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # VPN gateways
    #########################

    def list_ike_policies(self,
                          *,
                          start: str = None,
                          limit: int = None,
                          **kwargs) -> DetailedResponse:
        """
        List all IKE policies.

        This request retrieves a paginated list of all IKE policies that belong to this
        account.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IKEPolicyCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_ike_policies')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ike_policies'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_ike_policy(self,
                          authentication_algorithm: str,
                          dh_group: int,
                          encryption_algorithm: str,
                          ike_version: int,
                          *,
                          name: str = None,
                          key_lifetime: int = None,
                          resource_group: 'ResourceGroupIdentity' = None,
                          **kwargs) -> DetailedResponse:
        """
        Create an IKE policy.

        This request creates a new IKE policy.

        :param str authentication_algorithm: The authentication algorithm.
        :param int dh_group: The Diffie-Hellman group.
        :param str encryption_algorithm: The encryption algorithm.
        :param int ike_version: The IKE protocol version.
        :param str name: (optional) The user-defined name for this IKE policy.
        :param int key_lifetime: (optional) The key lifetime in seconds.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IKEPolicy` object
        """

        if authentication_algorithm is None:
            raise ValueError('authentication_algorithm must be provided')
        if dh_group is None:
            raise ValueError('dh_group must be provided')
        if encryption_algorithm is None:
            raise ValueError('encryption_algorithm must be provided')
        if ike_version is None:
            raise ValueError('ike_version must be provided')
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_ike_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'authentication_algorithm': authentication_algorithm,
            'dh_group': dh_group,
            'encryption_algorithm': encryption_algorithm,
            'ike_version': ike_version,
            'name': name,
            'key_lifetime': key_lifetime,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ike_policies'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_ike_policy(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete an IKE policy.

        This request deletes an IKE policy. This operation cannot be reversed.

        :param str id: The IKE policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_ike_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/ike_policies/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_ike_policy(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified IKE policy.

        This request retrieves a single IKE policy specified by the identifier in the URL.

        :param str id: The IKE policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IKEPolicy` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_ike_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ike_policies/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_ike_policy(self,
                          id: str,
                          *,
                          name: str = None,
                          authentication_algorithm: str = None,
                          dh_group: int = None,
                          encryption_algorithm: str = None,
                          ike_version: int = None,
                          key_lifetime: int = None,
                          **kwargs) -> DetailedResponse:
        """
        Update an IKE policy.

        This request updates the properties of an existing IKE policy.

        :param str id: The IKE policy identifier.
        :param str name: (optional) The user-defined name for this IKE policy.
        :param str authentication_algorithm: (optional) The authentication
               algorithm.
        :param int dh_group: (optional) The Diffie-Hellman group.
        :param str encryption_algorithm: (optional) The encryption algorithm.
        :param int ike_version: (optional) The IKE protocol version.
        :param int key_lifetime: (optional) The key lifetime in seconds.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IKEPolicy` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_ike_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'authentication_algorithm': authentication_algorithm,
            'dh_group': dh_group,
            'encryption_algorithm': encryption_algorithm,
            'ike_version': ike_version,
            'key_lifetime': key_lifetime
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ike_policies/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_ike_policy_connections(self, id: str,
                                    **kwargs) -> DetailedResponse:
        """
        List all connections that use the specified IKE policy.

        This request lists all the connections that use the specified policy.

        :param str id: The IKE policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnectionCollection` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_ike_policy_connections')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ike_policies/{0}/connections'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_ipsec_policies(self,
                            *,
                            start: str = None,
                            limit: int = None,
                            **kwargs) -> DetailedResponse:
        """
        List all IPsec policies.

        This request retrieves a paginated list of all IPsec policies that belong to this
        account.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IPsecPolicyCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_ipsec_policies')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ipsec_policies'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_ipsec_policy(self,
                            authentication_algorithm: str,
                            encryption_algorithm: str,
                            pfs: str,
                            *,
                            name: str = None,
                            key_lifetime: int = None,
                            resource_group: 'ResourceGroupIdentity' = None,
                            **kwargs) -> DetailedResponse:
        """
        Create an IPsec policy.

        This request creates a new IPsec policy.

        :param str authentication_algorithm: The authentication algorithm.
        :param str encryption_algorithm: The encryption algorithm.
        :param str pfs: Perfect Forward Secrecy.
        :param str name: (optional) The user-defined name for this IPsec policy.
        :param int key_lifetime: (optional) The key lifetime in seconds.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IPsecPolicy` object
        """

        if authentication_algorithm is None:
            raise ValueError('authentication_algorithm must be provided')
        if encryption_algorithm is None:
            raise ValueError('encryption_algorithm must be provided')
        if pfs is None:
            raise ValueError('pfs must be provided')
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_ipsec_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'authentication_algorithm': authentication_algorithm,
            'encryption_algorithm': encryption_algorithm,
            'pfs': pfs,
            'name': name,
            'key_lifetime': key_lifetime,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ipsec_policies'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_ipsec_policy(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete an IPsec policy.

        This request deletes an IPsec policy. This operation cannot be reversed.

        :param str id: The IPsec policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_ipsec_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/ipsec_policies/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_ipsec_policy(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified IPsec policy.

        This request retrieves a single IPsec policy specified by the identifier in the
        URL.

        :param str id: The IPsec policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IPsecPolicy` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_ipsec_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ipsec_policies/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_ipsec_policy(self,
                            id: str,
                            *,
                            name: str = None,
                            authentication_algorithm: str = None,
                            encryption_algorithm: str = None,
                            key_lifetime: int = None,
                            pfs: str = None,
                            **kwargs) -> DetailedResponse:
        """
        Update an IPsec policy.

        This request updates the properties of an existing IPsec policy.

        :param str id: The IPsec policy identifier.
        :param str name: (optional) The user-defined name for this IPsec policy.
        :param str authentication_algorithm: (optional) The authentication
               algorithm.
        :param str encryption_algorithm: (optional) The encryption algorithm.
        :param int key_lifetime: (optional) The key lifetime in seconds.
        :param str pfs: (optional) Perfect Forward Secrecy.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `IPsecPolicy` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_ipsec_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'authentication_algorithm': authentication_algorithm,
            'encryption_algorithm': encryption_algorithm,
            'key_lifetime': key_lifetime,
            'pfs': pfs
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ipsec_policies/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_ipsec_policy_connections(self, id: str,
                                      **kwargs) -> DetailedResponse:
        """
        List all connections that use the specified IPsec policy.

        This request lists all the connections that use the specified policy.

        :param str id: The IPsec policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnectionCollection` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_ipsec_policy_connections')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/ipsec_policies/{0}/connections'.format(
            *self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_vpn_gateways(self,
                          *,
                          start: str = None,
                          limit: int = None,
                          resource_group_id: str = None,
                          **kwargs) -> DetailedResponse:
        """
        List all VPN gateways.

        This request retrieves a paginated list of all VPN gateways that belong to this
        account.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_vpn_gateways')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_vpn_gateway(self,
                           subnet: 'SubnetIdentity',
                           *,
                           name: str = None,
                           resource_group: 'ResourceGroupIdentity' = None,
                           **kwargs) -> DetailedResponse:
        """
        Create a VPN gateway.

        This request creates a new VPN gateway.

        :param SubnetIdentity subnet: Identifies a subnet by a unique property.
        :param str name: (optional) The user-defined name for this VPN gateway.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGateway` object
        """

        if subnet is None:
            raise ValueError('subnet must be provided')
        subnet = convert_model(subnet)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_vpn_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'subnet': subnet,
            'name': name,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpn_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete a VPN gateway.

        This request deletes a VPN gateway. A VPN gateway with a `status` of `pending`
        cannot be deleted. This operation deletes all VPN gateway connections associated
        with this VPN gateway.  This operation cannot be reversed.

        :param str id: The VPN gateway identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_vpn_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpn_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified VPN gateway.

        This request retrieves a single VPN gateway specified by the identifier in the
        URL.

        :param str id: The VPN gateway identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGateway` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_vpn_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpn_gateway(self,
                           id: str,
                           *,
                           name: str = None,
                           **kwargs) -> DetailedResponse:
        """
        Update a VPN gateway.

        This request updates the properties of an existing VPN gateway.

        :param str id: The VPN gateway identifier.
        :param str name: (optional) The user-defined name for this VPN gateway.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGateway` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_vpn_gateway')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_vpn_gateway_connections(self,
                                     vpn_gateway_id: str,
                                     *,
                                     status: str = None,
                                     **kwargs) -> DetailedResponse:
        """
        List all connections of a VPN gateway.

        This request lists all the connections of a particular VPN gateway.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str status: (optional) Filters the collection to VPN gateway
               connections with the specified status.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnectionCollection` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpn_gateway_connections')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'status': status
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}/connections'.format(
            *self.encode_path_vars(vpn_gateway_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_vpn_gateway_connection(
            self,
            vpn_gateway_id: str,
            peer_address: str,
            psk: str,
            *,
            admin_state_up: bool = None,
            name: str = None,
            dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
            ike_policy: 'IKEPolicyIdentity' = None,
            ipsec_policy: 'IPsecPolicyIdentity' = None,
            local_cidrs: List[str] = None,
            peer_cidrs: List[str] = None,
            **kwargs) -> DetailedResponse:
        """
        Create a VPN gateway connection.

        This request creates a new VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The preshared key.
        :param bool admin_state_up: (optional) If set to false, the VPN connection
               is shut down.
        :param str name: (optional) The user-defined name for this VPN gateway
               connection.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional) The
               Dead Peer Detection settings.
        :param IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
               configuration. The absence of a policy indicates autonegotiation.
        :param IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
               configuration. The absence of a policy indicates
               autonegotiation.
        :param List[str] local_cidrs: (optional) A collection of local CIDRs for
               this resource.
        :param List[str] peer_cidrs: (optional) A collection of peer CIDRs for this
               resource.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnection` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if peer_address is None:
            raise ValueError('peer_address must be provided')
        if psk is None:
            raise ValueError('psk must be provided')
        if dead_peer_detection is not None:
            dead_peer_detection = convert_model(dead_peer_detection)
        if ike_policy is not None:
            ike_policy = convert_model(ike_policy)
        if ipsec_policy is not None:
            ipsec_policy = convert_model(ipsec_policy)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_vpn_gateway_connection')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'peer_address': peer_address,
            'psk': psk,
            'admin_state_up': admin_state_up,
            'name': name,
            'dead_peer_detection': dead_peer_detection,
            'ike_policy': ike_policy,
            'ipsec_policy': ipsec_policy,
            'local_cidrs': local_cidrs,
            'peer_cidrs': peer_cidrs
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}/connections'.format(
            *self.encode_path_vars(vpn_gateway_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpn_gateway_connection(self, vpn_gateway_id: str, id: str,
                                      **kwargs) -> DetailedResponse:
        """
        Delete a VPN gateway connection.

        This request deletes a VPN gateway connection. This operation cannot be reversed.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_vpn_gateway_connection')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}'.format(
            *self.encode_path_vars(vpn_gateway_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpn_gateway_connection(self, vpn_gateway_id: str, id: str,
                                   **kwargs) -> DetailedResponse:
        """
        Retrieve the specified VPN gateway connection.

        This request retrieves a single VPN gateway connection specified by the identifier
        in the URL.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnection` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_vpn_gateway_connection')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}/connections/{1}'.format(
            *self.encode_path_vars(vpn_gateway_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpn_gateway_connection(
            self,
            vpn_gateway_id: str,
            id: str,
            *,
            admin_state_up: bool = None,
            peer_address: str = None,
            name: str = None,
            psk: str = None,
            dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
            ike_policy: 'IKEPolicyIdentity' = None,
            ipsec_policy: 'IPsecPolicyIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Update a VPN gateway connection.

        This request updates the properties of an existing VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param bool admin_state_up: (optional) If set to false, the VPN connection
               is shut down.
        :param str peer_address: (optional) The IP address of the peer VPN gateway.
        :param str name: (optional) The user-defined name for this VPN gateway
               connection.
        :param str psk: (optional) The preshared key.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional) The
               Dead Peer Detection settings.
        :param IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
               configuration. The absence of a policy indicates autonegotiation.
        :param IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
               configuration. The absence of a policy indicates
               autonegotiation.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnection` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if dead_peer_detection is not None:
            dead_peer_detection = convert_model(dead_peer_detection)
        if ike_policy is not None:
            ike_policy = convert_model(ike_policy)
        if ipsec_policy is not None:
            ipsec_policy = convert_model(ipsec_policy)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_vpn_gateway_connection')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'admin_state_up': admin_state_up,
            'peer_address': peer_address,
            'name': name,
            'psk': psk,
            'dead_peer_detection': dead_peer_detection,
            'ike_policy': ike_policy,
            'ipsec_policy': ipsec_policy
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}/connections/{1}'.format(
            *self.encode_path_vars(vpn_gateway_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_vpn_gateway_connection_local_cidrs(self, vpn_gateway_id: str,
                                                id: str,
                                                **kwargs) -> DetailedResponse:
        """
        List all local CIDRs for a VPN gateway connection.

        This request lists all local CIDRs for a VPN gateway connection specified by the
        identifier in the URL.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnectionLocalCIDRs` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpn_gateway_connection_local_cidrs')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}/connections/{1}/local_cidrs'.format(
            *self.encode_path_vars(vpn_gateway_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def remove_vpn_gateway_connection_local_cidr(self, vpn_gateway_id: str,
                                                 id: str, cidr_prefix: str,
                                                 prefix_length: str,
                                                 **kwargs) -> DetailedResponse:
        """
        Remove a local CIDR from a VPN gateway connection.

        This request removes a CIDR from a VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param str cidr_prefix: The address prefix part of the CIDR.
        :param str prefix_length: The prefix length part of the CIDR.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if cidr_prefix is None:
            raise ValueError('cidr_prefix must be provided')
        if prefix_length is None:
            raise ValueError('prefix_length must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_vpn_gateway_connection_local_cidr')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}/local_cidrs/{2}/{3}'.format(
            *self.encode_path_vars(vpn_gateway_id, id, cidr_prefix,
                                   prefix_length))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def check_vpn_gateway_connection_local_cidr(self, vpn_gateway_id: str,
                                                id: str, cidr_prefix: str,
                                                prefix_length: str,
                                                **kwargs) -> DetailedResponse:
        """
        Check if the specified local CIDR exists on a VPN gateway connection.

        This request succeeds if a CIDR exists on the specified VPN gateway connection and
        fails otherwise.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param str cidr_prefix: The address prefix part of the CIDR.
        :param str prefix_length: The prefix length part of the CIDR.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if cidr_prefix is None:
            raise ValueError('cidr_prefix must be provided')
        if prefix_length is None:
            raise ValueError('prefix_length must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='check_vpn_gateway_connection_local_cidr')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}/local_cidrs/{2}/{3}'.format(
            *self.encode_path_vars(vpn_gateway_id, id, cidr_prefix,
                                   prefix_length))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def add_vpn_gateway_connection_local_cidr(self, vpn_gateway_id: str,
                                              id: str, cidr_prefix: str,
                                              prefix_length: str,
                                              **kwargs) -> DetailedResponse:
        """
        Set a local CIDR on a VPN gateway connection.

        This request adds the specified CIDR to the specified VPN gateway connection. A
        request body is not required, and if supplied, is ignored. This request succeeds
        if the CIDR already exists on the specified VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param str cidr_prefix: The address prefix part of the CIDR.
        :param str prefix_length: The prefix length part of the CIDR.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if cidr_prefix is None:
            raise ValueError('cidr_prefix must be provided')
        if prefix_length is None:
            raise ValueError('prefix_length must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_vpn_gateway_connection_local_cidr')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}/local_cidrs/{2}/{3}'.format(
            *self.encode_path_vars(vpn_gateway_id, id, cidr_prefix,
                                   prefix_length))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_vpn_gateway_connection_peer_cidrs(self, vpn_gateway_id: str,
                                               id: str,
                                               **kwargs) -> DetailedResponse:
        """
        List all peer CIDRs for a VPN gateway connection.

        This request lists all peer CIDRs for a VPN gateway connection specified by the
        identifier in the URL.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNGatewayConnectionPeerCIDRs` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpn_gateway_connection_peer_cidrs')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways/{0}/connections/{1}/peer_cidrs'.format(
            *self.encode_path_vars(vpn_gateway_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def remove_vpn_gateway_connection_peer_cidr(self, vpn_gateway_id: str,
                                                id: str, cidr_prefix: str,
                                                prefix_length: str,
                                                **kwargs) -> DetailedResponse:
        """
        Remove a peer CIDR from a VPN gateway connection.

        This request removes a CIDR from a VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param str cidr_prefix: The address prefix part of the CIDR.
        :param str prefix_length: The prefix length part of the CIDR.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if cidr_prefix is None:
            raise ValueError('cidr_prefix must be provided')
        if prefix_length is None:
            raise ValueError('prefix_length must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_vpn_gateway_connection_peer_cidr')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}/peer_cidrs/{2}/{3}'.format(
            *self.encode_path_vars(vpn_gateway_id, id, cidr_prefix,
                                   prefix_length))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def check_vpn_gateway_connection_peer_cidr(self, vpn_gateway_id: str,
                                               id: str, cidr_prefix: str,
                                               prefix_length: str,
                                               **kwargs) -> DetailedResponse:
        """
        Check if the specified peer CIDR exists on a VPN gateway connection.

        This request succeeds if a CIDR exists on the specified VPN gateway connection and
        fails otherwise.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param str cidr_prefix: The address prefix part of the CIDR.
        :param str prefix_length: The prefix length part of the CIDR.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if cidr_prefix is None:
            raise ValueError('cidr_prefix must be provided')
        if prefix_length is None:
            raise ValueError('prefix_length must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='check_vpn_gateway_connection_peer_cidr')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}/peer_cidrs/{2}/{3}'.format(
            *self.encode_path_vars(vpn_gateway_id, id, cidr_prefix,
                                   prefix_length))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def add_vpn_gateway_connection_peer_cidr(self, vpn_gateway_id: str, id: str,
                                             cidr_prefix: str,
                                             prefix_length: str,
                                             **kwargs) -> DetailedResponse:
        """
        Set a peer CIDR on a VPN gateway connection.

        This request adds the specified CIDR to the specified VPN gateway connection. A
        request body is not required, and if supplied, is ignored. This request succeeds
        if the CIDR already exists on the specified VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param str id: The VPN gateway connection identifier.
        :param str cidr_prefix: The address prefix part of the CIDR.
        :param str prefix_length: The prefix length part of the CIDR.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if cidr_prefix is None:
            raise ValueError('cidr_prefix must be provided')
        if prefix_length is None:
            raise ValueError('prefix_length must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_vpn_gateway_connection_peer_cidr')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/vpn_gateways/{0}/connections/{1}/peer_cidrs/{2}/{3}'.format(
            *self.encode_path_vars(vpn_gateway_id, id, cidr_prefix,
                                   prefix_length))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    #########################
    # Load balancers
    #########################

    def list_load_balancer_profiles(self,
                                    *,
                                    start: str = None,
                                    limit: int = None,
                                    **kwargs) -> DetailedResponse:
        """
        List all load balancer profiles.

        This request lists all load balancer profiles available in the region. A load
        balancer profile specifies the performance characteristics and pricing model for a
        load balancer.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerProfileCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_load_balancer_profiles')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancer/profiles'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer_profile(self, name: str,
                                  **kwargs) -> DetailedResponse:
        """
        Retrieve specified load balancer profile.

        This request retrieves a load balancer profile specified by the name in the URL.

        :param str name: The load balancer profile name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerProfile` object
        """

        if name is None:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_load_balancer_profile')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancer/profiles/{0}'.format(*self.encode_path_vars(name))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_load_balancers(self, **kwargs) -> DetailedResponse:
        """
        List all load balancers.

        This request retrieves a paginated list of all load balancers that belong to this
        account.

        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_load_balancers')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_load_balancer(
            self,
            is_public: bool,
            subnets: List['SubnetIdentity'],
            *,
            name: str = None,
            listeners: List[
                'LoadBalancerListenerPrototypeLoadBalancerContext'] = None,
            pools: List['LoadBalancerPoolPrototype'] = None,
            profile: 'LoadBalancerProfileIdentity' = None,
            resource_group: 'ResourceGroupIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Create and provision a load balancer.

        This request creates and provisions a new load balancer.

        :param bool is_public: The type of this load balancer, public or private.
        :param List[SubnetIdentity] subnets: The subnets to provision this load
               balancer.
        :param str name: (optional) The user-defined name for this load balancer.
               If unspecified, the name will be a hyphenated list of randomly-selected
               words.
        :param List[LoadBalancerListenerPrototypeLoadBalancerContext] listeners:
               (optional) The listeners of this load balancer.
        :param List[LoadBalancerPoolPrototype] pools: (optional) The pools of this
               load balancer.
        :param LoadBalancerProfileIdentity profile: (optional) The profile to use
               for this load balancer.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancer` object
        """

        if is_public is None:
            raise ValueError('is_public must be provided')
        if subnets is None:
            raise ValueError('subnets must be provided')
        subnets = [convert_model(x) for x in subnets]
        if listeners is not None:
            listeners = [convert_model(x) for x in listeners]
        if pools is not None:
            pools = [convert_model(x) for x in pools]
        if profile is not None:
            profile = convert_model(profile)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_load_balancer')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'is_public': is_public,
            'subnets': subnets,
            'name': name,
            'listeners': listeners,
            'pools': pools,
            'profile': profile,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_load_balancer(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete a load balancer.

        This request deletes a load balancer. This operation cannot be reversed.

        :param str id: The load balancer identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_load_balancer')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/load_balancers/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a load balancer.

        This request retrieves a single load balancer specified by the identifier in the
        URL path.

        :param str id: The load balancer identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancer` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_load_balancer')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_load_balancer(self,
                             id: str,
                             *,
                             name: str = None,
                             **kwargs) -> DetailedResponse:
        """
        Update a load balancer.

        This request updates a load balancer.

        :param str id: The load balancer identifier.
        :param str name: (optional) The unique user-defined name for this load
               balancer.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancer` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_load_balancer')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def get_load_balancer_statistics(self, id: str,
                                     **kwargs) -> DetailedResponse:
        """
        List statistics of a load balancer.

        This request lists statistics of a load balancer specified by the identifier in
        the URL path.

        :param str id: The load balancer identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerStatistics` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_load_balancer_statistics')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/statistics'.format(
            *self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_load_balancer_listeners(self, load_balancer_id: str,
                                     **kwargs) -> DetailedResponse:
        """
        List all listeners of the load balancer.

        This request retrieves a list of all listeners that belong to the load balancer.

        :param str load_balancer_id: The load balancer identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerCollection` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_load_balancer_listeners')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners'.format(
            *self.encode_path_vars(load_balancer_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_load_balancer_listener(
            self,
            load_balancer_id: str,
            port: int,
            protocol: str,
            *,
            connection_limit: int = None,
            certificate_instance: 'CertificateInstanceIdentity' = None,
            default_pool: 'LoadBalancerPoolIdentity' = None,
            policies: List['LoadBalancerListenerPolicyPrototype'] = None,
            **kwargs) -> DetailedResponse:
        """
        Create a listener.

        This request creates a new listener to the load balancer.

        :param str load_balancer_id: The load balancer identifier.
        :param int port: The listener port number.
        :param str protocol: The listener protocol. Load balancers in the `network`
               family support `tcp`. Load balancers in the `application` family support
               `tcp`, `http`, and `https`.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance used for SSL termination. It is applicable only to
               `https`
               protocol.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               associated with the listener.
        :param List[LoadBalancerListenerPolicyPrototype] policies: (optional) The
               list of policies of this listener.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListener` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if port is None:
            raise ValueError('port must be provided')
        if protocol is None:
            raise ValueError('protocol must be provided')
        if certificate_instance is not None:
            certificate_instance = convert_model(certificate_instance)
        if default_pool is not None:
            default_pool = convert_model(default_pool)
        if policies is not None:
            policies = [convert_model(x) for x in policies]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_load_balancer_listener')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'port': port,
            'protocol': protocol,
            'connection_limit': connection_limit,
            'certificate_instance': certificate_instance,
            'default_pool': default_pool,
            'policies': policies
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners'.format(
            *self.encode_path_vars(load_balancer_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_load_balancer_listener(self, load_balancer_id: str, id: str,
                                      **kwargs) -> DetailedResponse:
        """
        Delete a listener.

        This request deletes a load balancer listener. This operation cannot be reversed.

        :param str load_balancer_id: The load balancer identifier.
        :param str id: The listener identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_load_balancer_listener')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/load_balancers/{0}/listeners/{1}'.format(
            *self.encode_path_vars(load_balancer_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer_listener(self, load_balancer_id: str, id: str,
                                   **kwargs) -> DetailedResponse:
        """
        Retrieve a listener.

        This request retrieves a single listener specified by the identifier in the URL
        path.

        :param str load_balancer_id: The load balancer identifier.
        :param str id: The listener identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListener` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_load_balancer_listener')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}'.format(
            *self.encode_path_vars(load_balancer_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_load_balancer_listener(
            self,
            load_balancer_id: str,
            id: str,
            *,
            connection_limit: int = None,
            port: int = None,
            protocol: str = None,
            certificate_instance: 'CertificateInstanceIdentity' = None,
            default_pool: 'LoadBalancerPoolIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Update a listener.

        This request updates a load balancer listener from a listener patch.

        :param str load_balancer_id: The load balancer identifier.
        :param str id: The listener identifier.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param int port: (optional) The listener port number.
        :param str protocol: (optional) The listener protocol. Load balancers in
               the `network` family support `tcp`. Load balancers in the `application`
               family support `tcp`, `http`, and `https`.
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance used for SSL termination. It is applicable only to
               `https`
               protocol.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               associated with the listener.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListener` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if certificate_instance is not None:
            certificate_instance = convert_model(certificate_instance)
        if default_pool is not None:
            default_pool = convert_model(default_pool)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_load_balancer_listener')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'connection_limit': connection_limit,
            'port': port,
            'protocol': protocol,
            'certificate_instance': certificate_instance,
            'default_pool': default_pool
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}'.format(
            *self.encode_path_vars(load_balancer_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_load_balancer_listener_policies(self, load_balancer_id: str,
                                             listener_id: str,
                                             **kwargs) -> DetailedResponse:
        """
        List all policies of the load balancer listener.

        Retrieves a list of all policies belonging to the load balancer listener.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyCollection` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_load_balancer_listener_policies')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies'.format(
            *self.encode_path_vars(load_balancer_id, listener_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_load_balancer_listener_policy(
            self,
            load_balancer_id: str,
            listener_id: str,
            priority: int,
            action: str,
            *,
            name: str = None,
            rules: List['LoadBalancerListenerPolicyRulePrototype'] = None,
            target: 'LoadBalancerListenerPolicyPrototypeTarget' = None,
            **kwargs) -> DetailedResponse:
        """
        Create a policy for the load balancer listener.

        Creates a new policy to the load balancer listener.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str action: The policy action.
        :param str name: (optional) The user-defined name for this policy. Names
               must be unique within the load balancer listener the policy resides in.
        :param List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The
               list of rules of this policy.
        :param LoadBalancerListenerPolicyPrototypeTarget target: (optional) When
               `action` is `forward`, `LoadBalancerPoolIdentity` is required to specify
               which
               pool the load balancer forwards the traffic to. When `action` is
               `redirect`,
               `LoadBalancerListenerPolicyRedirectURLPrototype` is required to specify the
               url and
               http status code used in the redirect response.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicy` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if priority is None:
            raise ValueError('priority must be provided')
        if action is None:
            raise ValueError('action must be provided')
        if rules is not None:
            rules = [convert_model(x) for x in rules]
        if target is not None:
            target = convert_model(target)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_load_balancer_listener_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'priority': priority,
            'action': action,
            'name': name,
            'rules': rules,
            'target': target
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies'.format(
            *self.encode_path_vars(load_balancer_id, listener_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_load_balancer_listener_policy(self, load_balancer_id: str,
                                             listener_id: str, id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Delete a policy of the load balancer listener.

        Deletes a policy of the load balancer listener. This operation cannot be reversed.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str id: The policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_load_balancer_listener_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer_listener_policy(self, load_balancer_id: str,
                                          listener_id: str, id: str,
                                          **kwargs) -> DetailedResponse:
        """
        Retrieve a policy of the load balancer listener.

        Retrieve a single policy specified by the identifier in the URL path.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str id: The policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicy` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_load_balancer_listener_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_load_balancer_listener_policy(
            self,
            load_balancer_id: str,
            listener_id: str,
            id: str,
            *,
            name: str = None,
            priority: int = None,
            target: 'LoadBalancerListenerPolicyPatchTarget' = None,
            **kwargs) -> DetailedResponse:
        """
        Update a policy of the load balancer listener.

        Updates a policy from a policy patch.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str id: The policy identifier.
        :param str name: (optional) The user-defined name for this policy. Names
               must be unique within the load balancer listener the policy resides in.
        :param int priority: (optional) Priority of the policy. Lower value
               indicates higher priority.
        :param LoadBalancerListenerPolicyPatchTarget target: (optional) When
               `action` is `forward`, `LoadBalancerPoolIdentity` specifies which pool the
               load
               balancer forwards the traffic to. When `action` is `redirect`,
               `LoadBalancerListenerPolicyRedirectURLPatch` specifies the url and http
               status code used in the redirect response.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicy` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if target is not None:
            target = convert_model(target)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_load_balancer_listener_policy')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name, 'priority': priority, 'target': target}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_load_balancer_listener_policy_rules(self, load_balancer_id: str,
                                                 listener_id: str,
                                                 policy_id: str,
                                                 **kwargs) -> DetailedResponse:
        """
        List all rules of the load balancer listener policy.

        Retrieves a list of all rules belonging to the load balancer listener policy.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str policy_id: The policy identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyRuleCollection` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if policy_id is None:
            raise ValueError('policy_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_load_balancer_listener_policy_rules')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}/rules'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, policy_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_load_balancer_listener_policy_rule(self,
                                                  load_balancer_id: str,
                                                  listener_id: str,
                                                  policy_id: str,
                                                  condition: str,
                                                  type: str,
                                                  value: str,
                                                  *,
                                                  field: str = None,
                                                  **kwargs) -> DetailedResponse:
        """
        Create a rule for the load balancer listener policy.

        Creates a new rule for the load balancer listener policy.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str policy_id: The policy identifier.
        :param str condition: The condition of the rule.
        :param str type: The type of the rule.
        :param str value: Value to be matched for rule condition.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyRule` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if policy_id is None:
            raise ValueError('policy_id must be provided')
        if condition is None:
            raise ValueError('condition must be provided')
        if type is None:
            raise ValueError('type must be provided')
        if value is None:
            raise ValueError('value must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_load_balancer_listener_policy_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'condition': condition,
            'type': type,
            'value': value,
            'field': field
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}/rules'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, policy_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_load_balancer_listener_policy_rule(self, load_balancer_id: str,
                                                  listener_id: str,
                                                  policy_id: str, id: str,
                                                  **kwargs) -> DetailedResponse:
        """
        Delete a rule from the load balancer listener policy.

        Deletes a rule from the load balancer listener policy. This operation cannot be
        reversed.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str policy_id: The policy identifier.
        :param str id: The rule identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if policy_id is None:
            raise ValueError('policy_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_load_balancer_listener_policy_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}/rules/{3}'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, policy_id,
                                   id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer_listener_policy_rule(self, load_balancer_id: str,
                                               listener_id: str, policy_id: str,
                                               id: str,
                                               **kwargs) -> DetailedResponse:
        """
        Retrieve a rule of the load balancer listener policy.

        Retrieves a single rule specified by the identifier in the URL path.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str policy_id: The policy identifier.
        :param str id: The rule identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyRule` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if policy_id is None:
            raise ValueError('policy_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_load_balancer_listener_policy_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}/rules/{3}'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, policy_id,
                                   id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_load_balancer_listener_policy_rule(self,
                                                  load_balancer_id: str,
                                                  listener_id: str,
                                                  policy_id: str,
                                                  id: str,
                                                  *,
                                                  condition: str = None,
                                                  field: str = None,
                                                  type: str = None,
                                                  value: str = None,
                                                  **kwargs) -> DetailedResponse:
        """
        Update a rule of the load balancer listener policy.

        Updates a rule of the load balancer listener policy.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str policy_id: The policy identifier.
        :param str id: The rule identifier.
        :param str condition: (optional) The condition of the rule.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        :param str type: (optional) The type of the rule.
        :param str value: (optional) Value to be matched for rule condition.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyRule` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if policy_id is None:
            raise ValueError('policy_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_load_balancer_listener_policy_rule')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'condition': condition,
            'field': field,
            'type': type,
            'value': value
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/listeners/{1}/policies/{2}/rules/{3}'.format(
            *self.encode_path_vars(load_balancer_id, listener_id, policy_id,
                                   id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_load_balancer_pools(self, load_balancer_id: str,
                                 **kwargs) -> DetailedResponse:
        """
        List all pools of the load balancer.

        This request lists all pools that belong to the load balancer.

        :param str load_balancer_id: The load balancer identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolCollection` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_load_balancer_pools')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools'.format(
            *self.encode_path_vars(load_balancer_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_load_balancer_pool(
            self,
            load_balancer_id: str,
            algorithm: str,
            protocol: str,
            health_monitor: 'LoadBalancerPoolHealthMonitorPrototype',
            *,
            name: str = None,
            members: List['LoadBalancerPoolMemberPrototype'] = None,
            session_persistence:
        'LoadBalancerPoolSessionPersistencePrototype' = None,
            **kwargs) -> DetailedResponse:
        """
        Create a load balancer pool.

        This request creates a new pool from a pool prototype object.

        :param str load_balancer_id: The load balancer identifier.
        :param str algorithm: The load balancing algorithm.
        :param str protocol: The protocol used for this load balancer pool.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the pool on
               which the unexpected property value was encountered.
        :param LoadBalancerPoolHealthMonitorPrototype health_monitor: The health
               monitor of this pool.
        :param str name: (optional) The user-defined name for this load balancer
               pool. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param List[LoadBalancerPoolMemberPrototype] members: (optional) The
               members for this load balancer pool. For load balancers in the `network`
               family, the same `port` and `target` tuple cannot be shared by a member of
               any other load balancer.
        :param LoadBalancerPoolSessionPersistencePrototype session_persistence:
               (optional) The session persistence of this pool.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPool` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if algorithm is None:
            raise ValueError('algorithm must be provided')
        if protocol is None:
            raise ValueError('protocol must be provided')
        if health_monitor is None:
            raise ValueError('health_monitor must be provided')
        health_monitor = convert_model(health_monitor)
        if members is not None:
            members = [convert_model(x) for x in members]
        if session_persistence is not None:
            session_persistence = convert_model(session_persistence)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_load_balancer_pool')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'algorithm': algorithm,
            'protocol': protocol,
            'health_monitor': health_monitor,
            'name': name,
            'members': members,
            'session_persistence': session_persistence
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools'.format(
            *self.encode_path_vars(load_balancer_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_load_balancer_pool(self, load_balancer_id: str, id: str,
                                  **kwargs) -> DetailedResponse:
        """
        Delete a pool.

        This request deletes a load balancer pool. This operation cannot be reversed.

        :param str load_balancer_id: The load balancer identifier.
        :param str id: The pool identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_load_balancer_pool')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/load_balancers/{0}/pools/{1}'.format(
            *self.encode_path_vars(load_balancer_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer_pool(self, load_balancer_id: str, id: str,
                               **kwargs) -> DetailedResponse:
        """
        Retrieve a load balancer pool.

        This request retrieves a single pool specified by the identifier in the URL path.

        :param str load_balancer_id: The load balancer identifier.
        :param str id: The pool identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPool` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_load_balancer_pool')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}'.format(
            *self.encode_path_vars(load_balancer_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_load_balancer_pool(
            self,
            load_balancer_id: str,
            id: str,
            *,
            name: str = None,
            algorithm: str = None,
            protocol: str = None,
            health_monitor: 'LoadBalancerPoolHealthMonitorPatch' = None,
            session_persistence:
        'LoadBalancerPoolSessionPersistencePatch' = None,
            **kwargs) -> DetailedResponse:
        """
        Update a load balancer pool.

        This request updates a load balancer pool from a pool patch.

        :param str load_balancer_id: The load balancer identifier.
        :param str id: The pool identifier.
        :param str name: (optional) The user-defined name for this load balancer
               pool.
        :param str algorithm: (optional) The load balancing algorithm.
        :param str protocol: (optional) The protocol used for this load balancer
               pool.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the pool on
               which the unexpected property value was encountered.
        :param LoadBalancerPoolHealthMonitorPatch health_monitor: (optional) The
               health monitor of this pool.
        :param LoadBalancerPoolSessionPersistencePatch session_persistence:
               (optional) The session persistence of this pool.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPool` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if health_monitor is not None:
            health_monitor = convert_model(health_monitor)
        if session_persistence is not None:
            session_persistence = convert_model(session_persistence)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_load_balancer_pool')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'name': name,
            'algorithm': algorithm,
            'protocol': protocol,
            'health_monitor': health_monitor,
            'session_persistence': session_persistence
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}'.format(
            *self.encode_path_vars(load_balancer_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_load_balancer_pool_members(self, load_balancer_id: str,
                                        pool_id: str,
                                        **kwargs) -> DetailedResponse:
        """
        List all members of the load balancer pool.

        This request retrieves a paginated list of all members that belong to the pool.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolMemberCollection` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if pool_id is None:
            raise ValueError('pool_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_load_balancer_pool_members')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}/members'.format(
            *self.encode_path_vars(load_balancer_id, pool_id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_load_balancer_pool_member(
            self,
            load_balancer_id: str,
            pool_id: str,
            port: int,
            target: 'LoadBalancerPoolMemberTargetPrototype',
            *,
            weight: int = None,
            **kwargs) -> DetailedResponse:
        """
        Create a member in the load balancer pool.

        This request creates a new member and adds the member to the pool.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param int port: The port number of the application running in the server
               member.
        :param LoadBalancerPoolMemberTargetPrototype target: The pool member
               target. Load balancers in the `network` family
               support instances. Load balancers in the `application` family support
               IP addresses.
        :param int weight: (optional) Weight of the server member. This takes
               effect only when the load balancing algorithm of its belonging pool is
               `weighted_round_robin`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolMember` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if pool_id is None:
            raise ValueError('pool_id must be provided')
        if port is None:
            raise ValueError('port must be provided')
        if target is None:
            raise ValueError('target must be provided')
        target = convert_model(target)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_load_balancer_pool_member')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'port': port, 'target': target, 'weight': weight}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}/members'.format(
            *self.encode_path_vars(load_balancer_id, pool_id))
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def replace_load_balancer_pool_members(
            self, load_balancer_id: str, pool_id: str,
            members: List['LoadBalancerPoolMemberPrototype'],
            **kwargs) -> DetailedResponse:
        """
        Update members of the load balancer pool.

        This request updates members of the load balancer pool from a collection of member
        prototype objects.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param List[LoadBalancerPoolMemberPrototype] members: Array of pool member
               prototype objects.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolMemberCollection` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if pool_id is None:
            raise ValueError('pool_id must be provided')
        if members is None:
            raise ValueError('members must be provided')
        members = [convert_model(x) for x in members]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='replace_load_balancer_pool_members')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'members': members}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}/members'.format(
            *self.encode_path_vars(load_balancer_id, pool_id))
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_load_balancer_pool_member(self, load_balancer_id: str,
                                         pool_id: str, id: str,
                                         **kwargs) -> DetailedResponse:
        """
        Delete a member from the load balancer pool.

        This request deletes a member from the pool. This operation cannot be reversed.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param str id: The member identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if pool_id is None:
            raise ValueError('pool_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_load_balancer_pool_member')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/load_balancers/{0}/pools/{1}/members/{2}'.format(
            *self.encode_path_vars(load_balancer_id, pool_id, id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_load_balancer_pool_member(self, load_balancer_id: str, pool_id: str,
                                      id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a member in the load balancer pool.

        This request retrieves a single member specified by the identifier in the URL
        path.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param str id: The member identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolMember` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if pool_id is None:
            raise ValueError('pool_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_load_balancer_pool_member')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}/members/{2}'.format(
            *self.encode_path_vars(load_balancer_id, pool_id, id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_load_balancer_pool_member(
            self,
            load_balancer_id: str,
            pool_id: str,
            id: str,
            *,
            port: int = None,
            weight: int = None,
            target: 'LoadBalancerPoolMemberTargetPrototype' = None,
            **kwargs) -> DetailedResponse:
        """
        Update a member in the load balancer pool.

        This request updates an existing member from a member patch.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param str id: The member identifier.
        :param int port: (optional) The port number of the application running in
               the server member.
        :param int weight: (optional) Weight of the server member. This takes
               effect only when the load balancing algorithm of its belonging pool is
               `weighted_round_robin`.
        :param LoadBalancerPoolMemberTargetPrototype target: (optional) The pool
               member target. Load balancers in the `network` family
               support instances. Load balancers in the `application` family support
               IP addresses.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolMember` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if pool_id is None:
            raise ValueError('pool_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if target is not None:
            target = convert_model(target)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_load_balancer_pool_member')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'port': port, 'weight': weight, 'target': target}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/load_balancers/{0}/pools/{1}/members/{2}'.format(
            *self.encode_path_vars(load_balancer_id, pool_id, id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Flow log collectors
    #########################

    def list_flow_log_collectors(self,
                                 *,
                                 start: str = None,
                                 limit: int = None,
                                 resource_group_id: str = None,
                                 name: str = None,
                                 vpc_id: str = None,
                                 vpc_crn: str = None,
                                 vpc_name: str = None,
                                 target_id: str = None,
                                 target_resource_type: str = None,
                                 **kwargs) -> DetailedResponse:
        """
        List all flow log collectors.

        This request retrieves all flow log collectors in the region. A flow log collector
        summarizes data sent over one or more network interfaces within a VPC, depending
        on the chosen target.

        :param str start: (optional) A server-supplied token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources within one of the resource groups identified in a comma-separated
               list of resource group identifiers.
        :param str name: (optional) Filters the collection to resources with the
               exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources in the
               VPC with the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources in the
               VPC with the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources in the
               VPC with the exact specified name.
        :param str target_id: (optional) Filters the collection to flow log
               collectors that target the specified resource.
        :param str target_resource_type: (optional) Filters the collection to flow
               log collectors that target the specified resource type.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollectorCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_flow_log_collectors')
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'name': name,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name,
            'target.id': target_id,
            'target.resource_type': target_resource_type
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/flow_log_collectors'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_flow_log_collector(
            self,
            storage_bucket: 'CloudObjectStorageBucketIdentity',
            target: 'FlowLogCollectorPrototypeTarget',
            *,
            name: str = None,
            active: bool = None,
            resource_group: 'ResourceGroupIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Create a flow log collector.

        This request creates and starts a new flow log collector from a flow log collector
        prototype object. The prototype object is structured in the same way as a
        retrieved flow log collector, and contains the information necessary to create and
        start the new flow log collector.

        :param CloudObjectStorageBucketIdentity storage_bucket: The Cloud Object
               Storage bucket where the collected flows will be logged.
               The bucket must exist and an IAM service authorization must grant
               `IBM Cloud Flow Logs` resources of `VPC Infrastructure Services` writer
               access to the bucket.
        :param FlowLogCollectorPrototypeTarget target: The target this collector is
               to collect flow logs for. If the target is an instance,
               subnet, or VPC, flow logs will not be collected for any network interfaces
               within the
               target that are themselves the target of a more specific flow log
               collector.
        :param str name: (optional) The unique user-defined name for this flow log
               collector. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param bool active: (optional) Indicates whether this collector is active.
               If false, this collector is created in inactive mode.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollector` object
        """

        if storage_bucket is None:
            raise ValueError('storage_bucket must be provided')
        if target is None:
            raise ValueError('target must be provided')
        storage_bucket = convert_model(storage_bucket)
        target = convert_model(target)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_flow_log_collector')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {
            'storage_bucket': storage_bucket,
            'target': target,
            'name': name,
            'active': active,
            'resource_group': resource_group
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/flow_log_collectors'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_flow_log_collector(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete the specified flow log collector.

        This request stops and deletes a flow log collector. Collected flow logs remain
        available within the flow log collector's bucket.

        :param str id: The flow log collector identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_flow_log_collector')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))

        url = '/flow_log_collectors/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_flow_log_collector(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve the specified flow log collector.

        This request retrieves a single flow log collector specified by the identifier in
        the URL.

        :param str id: The flow log collector identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollector` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_flow_log_collector')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/flow_log_collectors/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_flow_log_collector(self,
                                  id: str,
                                  *,
                                  name: str = None,
                                  active: bool = None,
                                  **kwargs) -> DetailedResponse:
        """
        Update the specified flow log collector.

        This request updates a flow log collector with the information in a provided flow
        log collector patch. The flow log collector patch object is structured in the same
        way as a retrieved flow log collector and contains only the information to be
        updated.

        :param str id: The flow log collector identifier.
        :param str name: (optional) The unique user-defined name for this flow log
               collector.
        :param bool active: (optional) Indicates whether this collector is active.
               Updating to false deactivates the collector and updating to true activates
               the collector.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollector` object
        """

        if id is None:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='update_flow_log_collector')
        headers.update(sdk_headers)

        params = {'version': self.version, 'generation': self.generation}

        data = {'name': name, 'active': active}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/flow_log_collectors/{0}'.format(*self.encode_path_vars(id))
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response


class ListImagesEnums:
    """
    Enums for list_images parameters.
    """

    class Visibility(str, Enum):
        """
        Filters the collection to images with the specified `visibility`.
        """
        PRIVATE = 'private'
        PUBLIC = 'public'


class ListNetworkAclRulesEnums:
    """
    Enums for list_network_acl_rules parameters.
    """

    class Direction(str, Enum):
        """
        Filters the collection to rules with the specified direction.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


class ListFlowLogCollectorsEnums:
    """
    Enums for list_flow_log_collectors parameters.
    """

    class TargetResourceType(str, Enum):
        """
        Filters the collection to flow log collectors that target the specified resource
        type.
        """
        VPC = 'vpc'
        SUBNET = 'subnet'
        INSTANCE = 'instance'
        NETWORK_INTERFACE = 'network_interface'


##############################################################################
# Models
##############################################################################


class AddressPrefix():
    """
    AddressPrefix.

    :attr str id: The unique identifier for this address prefix.
    :attr str href: The URL for this address prefix.
    :attr str name: The user-defined name for this address prefix. Names must be
          unique within the VPC the address prefix resides in.
    :attr bool is_default: Indicates whether this is the default prefix for this
          zone in this VPC. If a default prefix was automatically created when the VPC was
          created, the prefix is automatically named using a hyphenated list of
          randomly-selected words, but may be updated with a user-specified name.
    :attr str cidr: The CIDR block for this prefix.
    :attr datetime created_at: The date and time that the prefix was created.
    :attr bool has_subnets: Indicates whether subnets exist with addresses from this
          prefix.
    :attr ZoneReference zone: The zone this address prefix resides in.
    """

    def __init__(self, id: str, href: str, name: str, is_default: bool,
                 cidr: str, created_at: datetime, has_subnets: bool,
                 zone: 'ZoneReference') -> None:
        """
        Initialize a AddressPrefix object.

        :param str id: The unique identifier for this address prefix.
        :param str href: The URL for this address prefix.
        :param str name: The user-defined name for this address prefix. Names must
               be unique within the VPC the address prefix resides in.
        :param bool is_default: Indicates whether this is the default prefix for
               this zone in this VPC. If a default prefix was automatically created when
               the VPC was created, the prefix is automatically named using a hyphenated
               list of randomly-selected words, but may be updated with a user-specified
               name.
        :param str cidr: The CIDR block for this prefix.
        :param datetime created_at: The date and time that the prefix was created.
        :param bool has_subnets: Indicates whether subnets exist with addresses
               from this prefix.
        :param ZoneReference zone: The zone this address prefix resides in.
        """
        self.id = id
        self.href = href
        self.name = name
        self.is_default = is_default
        self.cidr = cidr
        self.created_at = created_at
        self.has_subnets = has_subnets
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefix':
        """Initialize a AddressPrefix object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in AddressPrefix JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in AddressPrefix JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in AddressPrefix JSON')
        if 'is_default' in _dict:
            args['is_default'] = _dict.get('is_default')
        else:
            raise ValueError(
                'Required property \'is_default\' not present in AddressPrefix JSON'
            )
        if 'cidr' in _dict:
            args['cidr'] = _dict.get('cidr')
        else:
            raise ValueError(
                'Required property \'cidr\' not present in AddressPrefix JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in AddressPrefix JSON'
            )
        if 'has_subnets' in _dict:
            args['has_subnets'] = _dict.get('has_subnets')
        else:
            raise ValueError(
                'Required property \'has_subnets\' not present in AddressPrefix JSON'
            )
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in AddressPrefix JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefix object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        if hasattr(self, 'cidr') and self.cidr is not None:
            _dict['cidr'] = self.cidr
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'has_subnets') and self.has_subnets is not None:
            _dict['has_subnets'] = self.has_subnets
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefix object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefix') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefix') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixCollection():
    """
    AddressPrefixCollection.

    :attr AddressPrefixCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr AddressPrefixCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[AddressPrefix] address_prefixes: Collection of address prefixes.
    """

    def __init__(self,
                 first: 'AddressPrefixCollectionFirst',
                 limit: int,
                 total_count: int,
                 address_prefixes: List['AddressPrefix'],
                 *,
                 next: 'AddressPrefixCollectionNext' = None) -> None:
        """
        Initialize a AddressPrefixCollection object.

        :param AddressPrefixCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[AddressPrefix] address_prefixes: Collection of address
               prefixes.
        :param AddressPrefixCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.address_prefixes = address_prefixes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollection':
        """Initialize a AddressPrefixCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = AddressPrefixCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in AddressPrefixCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in AddressPrefixCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = AddressPrefixCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in AddressPrefixCollection JSON'
            )
        if 'address_prefixes' in _dict:
            args['address_prefixes'] = [
                AddressPrefix.from_dict(x)
                for x in _dict.get('address_prefixes')
            ]
        else:
            raise ValueError(
                'Required property \'address_prefixes\' not present in AddressPrefixCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self,
                   'address_prefixes') and self.address_prefixes is not None:
            _dict['address_prefixes'] = [
                x.to_dict() for x in self.address_prefixes
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefixCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a AddressPrefixCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollectionFirst':
        """Initialize a AddressPrefixCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in AddressPrefixCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefixCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a AddressPrefixCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollectionNext':
        """Initialize a AddressPrefixCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in AddressPrefixCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefixCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CertificateInstanceIdentity():
    """
    Identifies a certificate instance by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a CertificateInstanceIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['CertificateInstanceIdentityByCRN']))
        raise Exception(msg)


class CertificateInstanceReference():
    """
    CertificateInstanceReference.

    :attr str crn: The CRN for this certificate instance.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a CertificateInstanceReference object.

        :param str crn: The CRN for this certificate instance.
        """
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CertificateInstanceReference':
        """Initialize a CertificateInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in CertificateInstanceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CertificateInstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CertificateInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CertificateInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CertificateInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CloudObjectStorageBucketIdentity():
    """
    Identifies a Cloud Object Storage bucket by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a CloudObjectStorageBucketIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['CloudObjectStorageBucketIdentityByName']))
        raise Exception(msg)


class CloudObjectStorageBucketReference():
    """
    CloudObjectStorageBucketReference.

    :attr str name: The globally unique name of this COS bucket.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a CloudObjectStorageBucketReference object.

        :param str name: The globally unique name of this COS bucket.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CloudObjectStorageBucketReference':
        """Initialize a CloudObjectStorageBucketReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in CloudObjectStorageBucketReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CloudObjectStorageBucketReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CloudObjectStorageBucketReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CloudObjectStorageBucketReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CloudObjectStorageBucketReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DefaultNetworkACL():
    """
    DefaultNetworkACL.

    :attr str id: The unique identifier for this network ACL.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str name: The name of the default network ACL created for a VPC. The name
          will be a hyphenated list of randomly-selected words at creation, but may be
          user-specified with a subsequent request.
    :attr VPCReference vpc: The VPC this network ACL is a part of.
    :attr ResourceGroupReference resource_group: The resource group for the default
          network ACL for a VPC. Set to the VPC's
          resource group at creation.
    :attr datetime created_at: The date and time that the network ACL was created.
    :attr List[NetworkACLRuleItem] rules: The ordered rules for the default network
          ACL for a VPC.  Defaults to two rules which allow all inbound and outbound
          traffic, respectively.  Rules for the default network ACL may be changed, added,
          or removed.
    :attr List[SubnetReference] subnets: The subnets to which this network ACL is
          attached.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 vpc: 'VPCReference', resource_group: 'ResourceGroupReference',
                 created_at: datetime, rules: List['NetworkACLRuleItem'],
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a DefaultNetworkACL object.

        :param str id: The unique identifier for this network ACL.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str name: The name of the default network ACL created for a VPC. The
               name will be a hyphenated list of randomly-selected words at creation, but
               may be user-specified with a subsequent request.
        :param VPCReference vpc: The VPC this network ACL is a part of.
        :param ResourceGroupReference resource_group: The resource group for the
               default network ACL for a VPC. Set to the VPC's
               resource group at creation.
        :param datetime created_at: The date and time that the network ACL was
               created.
        :param List[NetworkACLRuleItem] rules: The ordered rules for the default
               network ACL for a VPC.  Defaults to two rules which allow all inbound and
               outbound traffic, respectively.  Rules for the default network ACL may be
               changed, added, or removed.
        :param List[SubnetReference] subnets: The subnets to which this network ACL
               is attached.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.vpc = vpc
        self.resource_group = resource_group
        self.created_at = created_at
        self.rules = rules
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultNetworkACL':
        """Initialize a DefaultNetworkACL object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DefaultNetworkACL JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DefaultNetworkACL JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DefaultNetworkACL JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DefaultNetworkACL JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in DefaultNetworkACL JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in DefaultNetworkACL JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in DefaultNetworkACL JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                NetworkACLRuleItem.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in DefaultNetworkACL JSON'
            )
        if 'subnets' in _dict:
            args['subnets'] = [
                SubnetReference.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in DefaultNetworkACL JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DefaultNetworkACL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'subnets') and self.subnets is not None:
            _dict['subnets'] = [x.to_dict() for x in self.subnets]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DefaultNetworkACL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DefaultNetworkACL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DefaultNetworkACL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DefaultSecurityGroup():
    """
    Collection of rules in a default security group.

    :attr str id: The unique identifier for this security group.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str name: The name of the default security group created for a VPC. The
          name will be a hyphenated list of randomly-selected words at creation, but may
          be user-specified with a subsequent request.
    :attr List[SecurityGroupRule] rules: Array of rules for the default security
          group for a VPC. Defaults to allowing all outbound traffic, and allowing all
          inbound traffic from other interfaces in the VPC’s default security group. Rules
          in the default security group may be changed, added or removed.
    :attr ResourceGroupReference resource_group: The resource group for this
          security group.
    :attr datetime created_at: The date and time that this security group was
          created.
    :attr VPCReference vpc: The VPC this security group is a part of.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 rules: List['SecurityGroupRule'],
                 resource_group: 'ResourceGroupReference', created_at: datetime,
                 vpc: 'VPCReference') -> None:
        """
        Initialize a DefaultSecurityGroup object.

        :param str id: The unique identifier for this security group.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str name: The name of the default security group created for a VPC.
               The name will be a hyphenated list of randomly-selected words at creation,
               but may be user-specified with a subsequent request.
        :param List[SecurityGroupRule] rules: Array of rules for the default
               security group for a VPC. Defaults to allowing all outbound traffic, and
               allowing all inbound traffic from other interfaces in the VPC’s default
               security group. Rules in the default security group may be changed, added
               or removed.
        :param ResourceGroupReference resource_group: The resource group for this
               security group.
        :param datetime created_at: The date and time that this security group was
               created.
        :param VPCReference vpc: The VPC this security group is a part of.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.rules = rules
        self.resource_group = resource_group
        self.created_at = created_at
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultSecurityGroup':
        """Initialize a DefaultSecurityGroup object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DefaultSecurityGroup JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DefaultSecurityGroup JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DefaultSecurityGroup JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DefaultSecurityGroup JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                SecurityGroupRule.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in DefaultSecurityGroup JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in DefaultSecurityGroup JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in DefaultSecurityGroup JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in DefaultSecurityGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DefaultSecurityGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DefaultSecurityGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DefaultSecurityGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DefaultSecurityGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EncryptionKeyIdentity():
    """
    Identifies an encryption key by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a EncryptionKeyIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EncryptionKeyIdentityByCRN']))
        raise Exception(msg)


class EncryptionKeyReference():
    """
    EncryptionKeyReference.

    :attr str crn: The CRN of the [Key Protect Root
          Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial)
          or [Hyper Protect Crypto Service Root
          Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for this
          resource.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a EncryptionKeyReference object.

        :param str crn: The CRN of the [Key Protect Root
               Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial)
               or [Hyper Protect Crypto Service Root
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for
               this resource.
        """
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EncryptionKeyReference':
        """Initialize a EncryptionKeyReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in EncryptionKeyReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EncryptionKeyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EncryptionKeyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EncryptionKeyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EncryptionKeyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIP():
    """
    FloatingIP.

    :attr str id: The unique identifier for this floating IP.
    :attr str crn: The CRN for this floating IP.
    :attr str href: The URL for this floating IP.
    :attr str address: The globally unique IP address.
    :attr str name: The unique user-defined name for this floating IP.
    :attr ResourceGroupReference resource_group: The resource group for this
          floating IP.
    :attr datetime created_at: The date and time that the floating IP was created.
    :attr str status: The status of the floating IP.
    :attr FloatingIPTarget target: (optional) The target of this floating IP.
    :attr ZoneReference zone: The zone the floating IP resides in.
    """

    def __init__(self,
                 id: str,
                 crn: str,
                 href: str,
                 address: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 created_at: datetime,
                 status: str,
                 zone: 'ZoneReference',
                 *,
                 target: 'FloatingIPTarget' = None) -> None:
        """
        Initialize a FloatingIP object.

        :param str id: The unique identifier for this floating IP.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str address: The globally unique IP address.
        :param str name: The unique user-defined name for this floating IP.
        :param ResourceGroupReference resource_group: The resource group for this
               floating IP.
        :param datetime created_at: The date and time that the floating IP was
               created.
        :param str status: The status of the floating IP.
        :param ZoneReference zone: The zone the floating IP resides in.
        :param FloatingIPTarget target: (optional) The target of this floating IP.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.address = address
        self.name = name
        self.resource_group = resource_group
        self.created_at = created_at
        self.status = status
        self.target = target
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIP':
        """Initialize a FloatingIP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIP JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FloatingIP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIP JSON')
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in FloatingIP JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FloatingIP JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in FloatingIP JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in FloatingIP JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in FloatingIP JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in FloatingIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the floating IP.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


class FloatingIPByTargetTarget():
    """
    The network interface this floating IP is to be bound to.

    """

    def __init__(self) -> None:
        """
        Initialize a FloatingIPByTargetTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FloatingIPByTargetTargetNetworkInterfaceIdentityById',
                'FloatingIPByTargetTargetNetworkInterfaceIdentityByHref'
            ]))
        raise Exception(msg)


class FloatingIPCollection():
    """
    FloatingIPCollection.

    :attr FloatingIPCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr FloatingIPCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[FloatingIP] floating_ips: Collection of floating IPs.
    """

    def __init__(self,
                 first: 'FloatingIPCollectionFirst',
                 limit: int,
                 total_count: int,
                 floating_ips: List['FloatingIP'],
                 *,
                 next: 'FloatingIPCollectionNext' = None) -> None:
        """
        Initialize a FloatingIPCollection object.

        :param FloatingIPCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[FloatingIP] floating_ips: Collection of floating IPs.
        :param FloatingIPCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.floating_ips = floating_ips

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPCollection':
        """Initialize a FloatingIPCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = FloatingIPCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in FloatingIPCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in FloatingIPCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = FloatingIPCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in FloatingIPCollection JSON'
            )
        if 'floating_ips' in _dict:
            args['floating_ips'] = [
                FloatingIP.from_dict(x) for x in _dict.get('floating_ips')
            ]
        else:
            raise ValueError(
                'Required property \'floating_ips\' not present in FloatingIPCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            _dict['floating_ips'] = [x.to_dict() for x in self.floating_ips]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPCollectionFirst':
        """Initialize a FloatingIPCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPCollectionNext':
        """Initialize a FloatingIPCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPatchTargetNetworkInterfaceIdentity():
    """
    A new network interface to bind this floating IP to, replacing any existing binding.
    For this request to succeed, the existing floating IP must not be required by another
    resource, such as a public gateway.

    """

    def __init__(self) -> None:
        """
        Initialize a FloatingIPPatchTargetNetworkInterfaceIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById',
                'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
            ]))
        raise Exception(msg)


class FloatingIPPrototype():
    """
    FloatingIPPrototype.

    :attr str name: (optional) The unique user-defined name for this floating IP. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a FloatingIPPrototype object.

        :param str name: (optional) The unique user-defined name for this floating
               IP. If unspecified, the name will be a hyphenated list of randomly-selected
               words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FloatingIPPrototypeFloatingIPByZone',
                'FloatingIPPrototypeFloatingIPByTarget'
            ]))
        raise Exception(msg)


class FloatingIPReference():
    """
    FloatingIPReference.

    :attr str id: The unique identifier for this floating IP.
    :attr str crn: The CRN for this floating IP.
    :attr str href: The URL for this floating IP.
    :attr str address: The globally unique IP address.
    :attr str name: The unique user-defined name for this floating IP.
    """

    def __init__(self, id: str, crn: str, href: str, address: str,
                 name: str) -> None:
        """
        Initialize a FloatingIPReference object.

        :param str id: The unique identifier for this floating IP.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str address: The globally unique IP address.
        :param str name: The unique user-defined name for this floating IP.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.address = address
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPReference':
        """Initialize a FloatingIPReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIPReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FloatingIPReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPReference JSON'
            )
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in FloatingIPReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FloatingIPReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTarget():
    """
    The target of this floating IP.

    """

    def __init__(self) -> None:
        """
        Initialize a FloatingIPTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FloatingIPTargetNetworkInterfaceReference',
                'FloatingIPTargetPublicGatewayReference'
            ]))
        raise Exception(msg)


class FloatingIPUnpaginatedCollection():
    """
    FloatingIPUnpaginatedCollection.

    :attr List[FloatingIP] floating_ips: Collection of floating IPs.
    """

    def __init__(self, floating_ips: List['FloatingIP']) -> None:
        """
        Initialize a FloatingIPUnpaginatedCollection object.

        :param List[FloatingIP] floating_ips: Collection of floating IPs.
        """
        self.floating_ips = floating_ips

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPUnpaginatedCollection':
        """Initialize a FloatingIPUnpaginatedCollection object from a json dictionary."""
        args = {}
        if 'floating_ips' in _dict:
            args['floating_ips'] = [
                FloatingIP.from_dict(x) for x in _dict.get('floating_ips')
            ]
        else:
            raise ValueError(
                'Required property \'floating_ips\' not present in FloatingIPUnpaginatedCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPUnpaginatedCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            _dict['floating_ips'] = [x.to_dict() for x in self.floating_ips]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPUnpaginatedCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPUnpaginatedCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPUnpaginatedCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollector():
    """
    FlowLogCollector.

    :attr str id: The unique identifier for this flow log collector.
    :attr str crn: The CRN for this flow log collector.
    :attr str href: The URL for this flow log collector.
    :attr str name: The unique user-defined name for this flow log collector.
    :attr ResourceGroupReference resource_group: The resource group for this flow
          log collector.
    :attr bool active: Indicates whether this collector is active.
    :attr bool auto_delete: If set to `true`, this flow log collector will be
          automatically deleted when the target is deleted.
    :attr datetime created_at: The date and time that the flow log collector was
          created.
    :attr str lifecycle_state: The lifecycle state of the flow log collector.
    :attr CloudObjectStorageBucketReference storage_bucket: The Cloud Object Storage
          bucket where the collected flows are logged.
    :attr FlowLogCollectorTarget target: The target this collector is collecting
          flow logs for. If the target is an instance,
          subnet, or VPC, flow logs will not be collected for any network interfaces
          within the
          target that are themselves the target of a more specific flow log collector.
    :attr VPCReference vpc: The VPC this flow log collector is associated with.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 resource_group: 'ResourceGroupReference', active: bool,
                 auto_delete: bool, created_at: datetime, lifecycle_state: str,
                 storage_bucket: 'CloudObjectStorageBucketReference',
                 target: 'FlowLogCollectorTarget', vpc: 'VPCReference') -> None:
        """
        Initialize a FlowLogCollector object.

        :param str id: The unique identifier for this flow log collector.
        :param str crn: The CRN for this flow log collector.
        :param str href: The URL for this flow log collector.
        :param str name: The unique user-defined name for this flow log collector.
        :param ResourceGroupReference resource_group: The resource group for this
               flow log collector.
        :param bool active: Indicates whether this collector is active.
        :param bool auto_delete: If set to `true`, this flow log collector will be
               automatically deleted when the target is deleted.
        :param datetime created_at: The date and time that the flow log collector
               was created.
        :param str lifecycle_state: The lifecycle state of the flow log collector.
        :param CloudObjectStorageBucketReference storage_bucket: The Cloud Object
               Storage bucket where the collected flows are logged.
        :param FlowLogCollectorTarget target: The target this collector is
               collecting flow logs for. If the target is an instance,
               subnet, or VPC, flow logs will not be collected for any network interfaces
               within the
               target that are themselves the target of a more specific flow log
               collector.
        :param VPCReference vpc: The VPC this flow log collector is associated
               with.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_group = resource_group
        self.active = active
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.lifecycle_state = lifecycle_state
        self.storage_bucket = storage_bucket
        self.target = target
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollector':
        """Initialize a FlowLogCollector object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollector JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollector JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollector JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FlowLogCollector JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in FlowLogCollector JSON'
            )
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        else:
            raise ValueError(
                'Required property \'active\' not present in FlowLogCollector JSON'
            )
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError(
                'Required property \'auto_delete\' not present in FlowLogCollector JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in FlowLogCollector JSON'
            )
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' not present in FlowLogCollector JSON'
            )
        if 'storage_bucket' in _dict:
            args[
                'storage_bucket'] = CloudObjectStorageBucketReference.from_dict(
                    _dict.get('storage_bucket'))
        else:
            raise ValueError(
                'Required property \'storage_bucket\' not present in FlowLogCollector JSON'
            )
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError(
                'Required property \'target\' not present in FlowLogCollector JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in FlowLogCollector JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollector object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'storage_bucket') and self.storage_bucket is not None:
            _dict['storage_bucket'] = self.storage_bucket.to_dict()
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollector object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollector') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollector') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the flow log collector.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'


class FlowLogCollectorCollection():
    """
    FlowLogCollectorCollection.

    :attr FlowLogCollectorCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr FlowLogCollectorCollectionNext next: (optional) A reference to the next
          page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[FlowLogCollector] flow_log_collectors: Collection of flow log
          collectors.
    """

    def __init__(self,
                 first: 'FlowLogCollectorCollectionFirst',
                 limit: int,
                 total_count: int,
                 flow_log_collectors: List['FlowLogCollector'],
                 *,
                 next: 'FlowLogCollectorCollectionNext' = None) -> None:
        """
        Initialize a FlowLogCollectorCollection object.

        :param FlowLogCollectorCollectionFirst first: A reference to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[FlowLogCollector] flow_log_collectors: Collection of flow log
               collectors.
        :param FlowLogCollectorCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.flow_log_collectors = flow_log_collectors

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorCollection':
        """Initialize a FlowLogCollectorCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = FlowLogCollectorCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in FlowLogCollectorCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in FlowLogCollectorCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = FlowLogCollectorCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in FlowLogCollectorCollection JSON'
            )
        if 'flow_log_collectors' in _dict:
            args['flow_log_collectors'] = [
                FlowLogCollector.from_dict(x)
                for x in _dict.get('flow_log_collectors')
            ]
        else:
            raise ValueError(
                'Required property \'flow_log_collectors\' not present in FlowLogCollectorCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(
                self,
                'flow_log_collectors') and self.flow_log_collectors is not None:
            _dict['flow_log_collectors'] = [
                x.to_dict() for x in self.flow_log_collectors
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorCollectionFirst':
        """Initialize a FlowLogCollectorCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorCollectionNext':
        """Initialize a FlowLogCollectorCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTarget():
    """
    The target this collector is to collect flow logs for. If the target is an instance,
    subnet, or VPC, flow logs will not be collected for any network interfaces within the
    target that are themselves the target of a more specific flow log collector.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentity',
                'FlowLogCollectorPrototypeTargetInstanceIdentity',
                'FlowLogCollectorPrototypeTargetSubnetIdentity',
                'FlowLogCollectorPrototypeTargetVPCIdentity'
            ]))
        raise Exception(msg)


class FlowLogCollectorTarget():
    """
    The target this collector is collecting flow logs for. If the target is an instance,
    subnet, or VPC, flow logs will not be collected for any network interfaces within the
    target that are themselves the target of a more specific flow log collector.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext',
                'FlowLogCollectorTargetInstanceReference',
                'FlowLogCollectorTargetSubnetReference',
                'FlowLogCollectorTargetVPCReference'
            ]))
        raise Exception(msg)


class IKEPolicy():
    """
    IKEPolicy.

    :attr str id: The unique identifier for this IKE policy.
    :attr str href: The IKE policy's canonical URL.
    :attr str name: The user-defined name for this IKE policy.
    :attr str resource_type: The resource type.
    :attr str authentication_algorithm: The authentication algorithm.
    :attr int dh_group: The Diffie-Hellman group.
    :attr str encryption_algorithm: The encryption algorithm.
    :attr int ike_version: The IKE protocol version.
    :attr int key_lifetime: The key lifetime in seconds.
    :attr ResourceGroupReference resource_group: The resource group for this IKE
          policy.
    :attr List[VPNGatewayConnectionReference] connections: Collection of references
          to VPN gateway connections that use this IKE policy.
    :attr datetime created_at: The date and time that this IKE policy was created.
    :attr str negotiation_mode: The IKE negotiation mode. Only `main` is supported.
    """

    def __init__(self, id: str, href: str, name: str, resource_type: str,
                 authentication_algorithm: str, dh_group: int,
                 encryption_algorithm: str, ike_version: int, key_lifetime: int,
                 resource_group: 'ResourceGroupReference',
                 connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, negotiation_mode: str) -> None:
        """
        Initialize a IKEPolicy object.

        :param str id: The unique identifier for this IKE policy.
        :param str href: The IKE policy's canonical URL.
        :param str name: The user-defined name for this IKE policy.
        :param str resource_type: The resource type.
        :param str authentication_algorithm: The authentication algorithm.
        :param int dh_group: The Diffie-Hellman group.
        :param str encryption_algorithm: The encryption algorithm.
        :param int ike_version: The IKE protocol version.
        :param int key_lifetime: The key lifetime in seconds.
        :param ResourceGroupReference resource_group: The resource group for this
               IKE policy.
        :param List[VPNGatewayConnectionReference] connections: Collection of
               references to VPN gateway connections that use this IKE policy.
        :param datetime created_at: The date and time that this IKE policy was
               created.
        :param str negotiation_mode: The IKE negotiation mode. Only `main` is
               supported.
        """
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type
        self.authentication_algorithm = authentication_algorithm
        self.dh_group = dh_group
        self.encryption_algorithm = encryption_algorithm
        self.ike_version = ike_version
        self.key_lifetime = key_lifetime
        self.resource_group = resource_group
        self.connections = connections
        self.created_at = created_at
        self.negotiation_mode = negotiation_mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicy':
        """Initialize a IKEPolicy object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in IKEPolicy JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicy JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in IKEPolicy JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in IKEPolicy JSON'
            )
        if 'authentication_algorithm' in _dict:
            args['authentication_algorithm'] = _dict.get(
                'authentication_algorithm')
        else:
            raise ValueError(
                'Required property \'authentication_algorithm\' not present in IKEPolicy JSON'
            )
        if 'dh_group' in _dict:
            args['dh_group'] = _dict.get('dh_group')
        else:
            raise ValueError(
                'Required property \'dh_group\' not present in IKEPolicy JSON')
        if 'encryption_algorithm' in _dict:
            args['encryption_algorithm'] = _dict.get('encryption_algorithm')
        else:
            raise ValueError(
                'Required property \'encryption_algorithm\' not present in IKEPolicy JSON'
            )
        if 'ike_version' in _dict:
            args['ike_version'] = _dict.get('ike_version')
        else:
            raise ValueError(
                'Required property \'ike_version\' not present in IKEPolicy JSON'
            )
        if 'key_lifetime' in _dict:
            args['key_lifetime'] = _dict.get('key_lifetime')
        else:
            raise ValueError(
                'Required property \'key_lifetime\' not present in IKEPolicy JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in IKEPolicy JSON'
            )
        if 'connections' in _dict:
            args['connections'] = [
                VPNGatewayConnectionReference.from_dict(x)
                for x in _dict.get('connections')
            ]
        else:
            raise ValueError(
                'Required property \'connections\' not present in IKEPolicy JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in IKEPolicy JSON'
            )
        if 'negotiation_mode' in _dict:
            args['negotiation_mode'] = _dict.get('negotiation_mode')
        else:
            raise ValueError(
                'Required property \'negotiation_mode\' not present in IKEPolicy JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'authentication_algorithm'
                  ) and self.authentication_algorithm is not None:
            _dict['authentication_algorithm'] = self.authentication_algorithm
        if hasattr(self, 'dh_group') and self.dh_group is not None:
            _dict['dh_group'] = self.dh_group
        if hasattr(self, 'encryption_algorithm'
                  ) and self.encryption_algorithm is not None:
            _dict['encryption_algorithm'] = self.encryption_algorithm
        if hasattr(self, 'ike_version') and self.ike_version is not None:
            _dict['ike_version'] = self.ike_version
        if hasattr(self, 'key_lifetime') and self.key_lifetime is not None:
            _dict['key_lifetime'] = self.key_lifetime
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'connections') and self.connections is not None:
            _dict['connections'] = [x.to_dict() for x in self.connections]
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self,
                   'negotiation_mode') and self.negotiation_mode is not None:
            _dict['negotiation_mode'] = self.negotiation_mode
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        IKE_POLICY = 'ike_policy'

    class AuthenticationAlgorithmEnum(str, Enum):
        """
        The authentication algorithm.
        """
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'

    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        """
        TRIPLE_DES = 'triple_des'
        AES128 = 'aes128'
        AES256 = 'aes256'

    class NegotiationModeEnum(str, Enum):
        """
        The IKE negotiation mode. Only `main` is supported.
        """
        MAIN = 'main'


class IKEPolicyCollection():
    """
    IKEPolicyCollection.

    :attr IKEPolicyCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr IKEPolicyCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[IKEPolicy] ike_policies: Collection of IKE policies.
    """

    def __init__(self,
                 first: 'IKEPolicyCollectionFirst',
                 limit: int,
                 total_count: int,
                 ike_policies: List['IKEPolicy'],
                 *,
                 next: 'IKEPolicyCollectionNext' = None) -> None:
        """
        Initialize a IKEPolicyCollection object.

        :param IKEPolicyCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[IKEPolicy] ike_policies: Collection of IKE policies.
        :param IKEPolicyCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.ike_policies = ike_policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyCollection':
        """Initialize a IKEPolicyCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = IKEPolicyCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in IKEPolicyCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in IKEPolicyCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = IKEPolicyCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in IKEPolicyCollection JSON'
            )
        if 'ike_policies' in _dict:
            args['ike_policies'] = [
                IKEPolicy.from_dict(x) for x in _dict.get('ike_policies')
            ]
        else:
            raise ValueError(
                'Required property \'ike_policies\' not present in IKEPolicyCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'ike_policies') and self.ike_policies is not None:
            _dict['ike_policies'] = [x.to_dict() for x in self.ike_policies]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IKEPolicyCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IKEPolicyCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyCollectionFirst':
        """Initialize a IKEPolicyCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicyCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IKEPolicyCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IKEPolicyCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyCollectionNext':
        """Initialize a IKEPolicyCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicyCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IKEPolicyIdentity():
    """
    Identifies an IKE policy by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a IKEPolicyIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['IKEPolicyIdentityById', 'IKEPolicyIdentityByHref']))
        raise Exception(msg)


class IKEPolicyReference():
    """
    IKEPolicyReference.

    :attr str id: The unique identifier for this IKE policy.
    :attr str href: The IKE policy's canonical URL.
    :attr str name: The user-defined name for this IKE policy.
    :attr str resource_type: The resource type.
    """

    def __init__(self, id: str, href: str, name: str,
                 resource_type: str) -> None:
        """
        Initialize a IKEPolicyReference object.

        :param str id: The unique identifier for this IKE policy.
        :param str href: The IKE policy's canonical URL.
        :param str name: The user-defined name for this IKE policy.
        :param str resource_type: The resource type.
        """
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyReference':
        """Initialize a IKEPolicyReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in IKEPolicyReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicyReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in IKEPolicyReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in IKEPolicyReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        IKE_POLICY = 'ike_policy'


class IP():
    """
    IP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a IP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IP':
        """Initialize a IP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in IP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicy():
    """
    IPsecPolicy.

    :attr str id: The unique identifier for this IPsec policy.
    :attr str href: The IPsec policy's canonical URL.
    :attr str name: The user-defined name for this IPsec policy.
    :attr str resource_type: The resource type.
    :attr str authentication_algorithm: The authentication algorithm.
    :attr str encryption_algorithm: The encryption algorithm.
    :attr int key_lifetime: The key lifetime in seconds.
    :attr str pfs: Perfect Forward Secrecy.
    :attr ResourceGroupReference resource_group: The resource group for this IPsec
          policy.
    :attr List[VPNGatewayConnectionReference] connections: Collection of references
          to VPN gateway connections that use this IPsec policy.
    :attr datetime created_at: The date and time that this IPsec policy was created.
    :attr str encapsulation_mode: The encapsulation mode used. Only `tunnel` is
          supported.
    :attr str transform_protocol: The transform protocol used. Only `esp` is
          supported.
    """

    def __init__(self, id: str, href: str, name: str, resource_type: str,
                 authentication_algorithm: str, encryption_algorithm: str,
                 key_lifetime: int, pfs: str,
                 resource_group: 'ResourceGroupReference',
                 connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, encapsulation_mode: str,
                 transform_protocol: str) -> None:
        """
        Initialize a IPsecPolicy object.

        :param str id: The unique identifier for this IPsec policy.
        :param str href: The IPsec policy's canonical URL.
        :param str name: The user-defined name for this IPsec policy.
        :param str resource_type: The resource type.
        :param str authentication_algorithm: The authentication algorithm.
        :param str encryption_algorithm: The encryption algorithm.
        :param int key_lifetime: The key lifetime in seconds.
        :param str pfs: Perfect Forward Secrecy.
        :param ResourceGroupReference resource_group: The resource group for this
               IPsec policy.
        :param List[VPNGatewayConnectionReference] connections: Collection of
               references to VPN gateway connections that use this IPsec policy.
        :param datetime created_at: The date and time that this IPsec policy was
               created.
        :param str encapsulation_mode: The encapsulation mode used. Only `tunnel`
               is supported.
        :param str transform_protocol: The transform protocol used. Only `esp` is
               supported.
        """
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type
        self.authentication_algorithm = authentication_algorithm
        self.encryption_algorithm = encryption_algorithm
        self.key_lifetime = key_lifetime
        self.pfs = pfs
        self.resource_group = resource_group
        self.connections = connections
        self.created_at = created_at
        self.encapsulation_mode = encapsulation_mode
        self.transform_protocol = transform_protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicy':
        """Initialize a IPsecPolicy object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in IPsecPolicy JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IPsecPolicy JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in IPsecPolicy JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in IPsecPolicy JSON'
            )
        if 'authentication_algorithm' in _dict:
            args['authentication_algorithm'] = _dict.get(
                'authentication_algorithm')
        else:
            raise ValueError(
                'Required property \'authentication_algorithm\' not present in IPsecPolicy JSON'
            )
        if 'encryption_algorithm' in _dict:
            args['encryption_algorithm'] = _dict.get('encryption_algorithm')
        else:
            raise ValueError(
                'Required property \'encryption_algorithm\' not present in IPsecPolicy JSON'
            )
        if 'key_lifetime' in _dict:
            args['key_lifetime'] = _dict.get('key_lifetime')
        else:
            raise ValueError(
                'Required property \'key_lifetime\' not present in IPsecPolicy JSON'
            )
        if 'pfs' in _dict:
            args['pfs'] = _dict.get('pfs')
        else:
            raise ValueError(
                'Required property \'pfs\' not present in IPsecPolicy JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in IPsecPolicy JSON'
            )
        if 'connections' in _dict:
            args['connections'] = [
                VPNGatewayConnectionReference.from_dict(x)
                for x in _dict.get('connections')
            ]
        else:
            raise ValueError(
                'Required property \'connections\' not present in IPsecPolicy JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in IPsecPolicy JSON'
            )
        if 'encapsulation_mode' in _dict:
            args['encapsulation_mode'] = _dict.get('encapsulation_mode')
        else:
            raise ValueError(
                'Required property \'encapsulation_mode\' not present in IPsecPolicy JSON'
            )
        if 'transform_protocol' in _dict:
            args['transform_protocol'] = _dict.get('transform_protocol')
        else:
            raise ValueError(
                'Required property \'transform_protocol\' not present in IPsecPolicy JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'authentication_algorithm'
                  ) and self.authentication_algorithm is not None:
            _dict['authentication_algorithm'] = self.authentication_algorithm
        if hasattr(self, 'encryption_algorithm'
                  ) and self.encryption_algorithm is not None:
            _dict['encryption_algorithm'] = self.encryption_algorithm
        if hasattr(self, 'key_lifetime') and self.key_lifetime is not None:
            _dict['key_lifetime'] = self.key_lifetime
        if hasattr(self, 'pfs') and self.pfs is not None:
            _dict['pfs'] = self.pfs
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'connections') and self.connections is not None:
            _dict['connections'] = [x.to_dict() for x in self.connections]
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(
                self,
                'encapsulation_mode') and self.encapsulation_mode is not None:
            _dict['encapsulation_mode'] = self.encapsulation_mode
        if hasattr(
                self,
                'transform_protocol') and self.transform_protocol is not None:
            _dict['transform_protocol'] = self.transform_protocol
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        IPSEC_POLICY = 'ipsec_policy'

    class AuthenticationAlgorithmEnum(str, Enum):
        """
        The authentication algorithm.
        """
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'

    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        """
        TRIPLE_DES = 'triple_des'
        AES128 = 'aes128'
        AES256 = 'aes256'

    class PfsEnum(str, Enum):
        """
        Perfect Forward Secrecy.
        """
        DISABLED = 'disabled'
        GROUP_14 = 'group_14'
        GROUP_2 = 'group_2'
        GROUP_5 = 'group_5'

    class EncapsulationModeEnum(str, Enum):
        """
        The encapsulation mode used. Only `tunnel` is supported.
        """
        TUNNEL = 'tunnel'

    class TransformProtocolEnum(str, Enum):
        """
        The transform protocol used. Only `esp` is supported.
        """
        ESP = 'esp'


class IPsecPolicyCollection():
    """
    IPsecPolicyCollection.

    :attr IPsecPolicyCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr IPsecPolicyCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[IPsecPolicy] ipsec_policies: Collection of IPsec policies.
    """

    def __init__(self,
                 first: 'IPsecPolicyCollectionFirst',
                 limit: int,
                 total_count: int,
                 ipsec_policies: List['IPsecPolicy'],
                 *,
                 next: 'IPsecPolicyCollectionNext' = None) -> None:
        """
        Initialize a IPsecPolicyCollection object.

        :param IPsecPolicyCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[IPsecPolicy] ipsec_policies: Collection of IPsec policies.
        :param IPsecPolicyCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.ipsec_policies = ipsec_policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyCollection':
        """Initialize a IPsecPolicyCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = IPsecPolicyCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in IPsecPolicyCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in IPsecPolicyCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = IPsecPolicyCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in IPsecPolicyCollection JSON'
            )
        if 'ipsec_policies' in _dict:
            args['ipsec_policies'] = [
                IPsecPolicy.from_dict(x) for x in _dict.get('ipsec_policies')
            ]
        else:
            raise ValueError(
                'Required property \'ipsec_policies\' not present in IPsecPolicyCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'ipsec_policies') and self.ipsec_policies is not None:
            _dict['ipsec_policies'] = [x.to_dict() for x in self.ipsec_policies]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicyCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IPsecPolicyCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyCollectionFirst':
        """Initialize a IPsecPolicyCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IPsecPolicyCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicyCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IPsecPolicyCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyCollectionNext':
        """Initialize a IPsecPolicyCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IPsecPolicyCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicyIdentity():
    """
    Identifies an IPsec policy by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a IPsecPolicyIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['IPsecPolicyIdentityById', 'IPsecPolicyIdentityByHref']))
        raise Exception(msg)


class IPsecPolicyReference():
    """
    IPsecPolicyReference.

    :attr str id: The unique identifier for this IPsec policy.
    :attr str href: The IPsec policy's canonical URL.
    :attr str name: The user-defined name for this IPsec policy.
    :attr str resource_type: The resource type.
    """

    def __init__(self, id: str, href: str, name: str,
                 resource_type: str) -> None:
        """
        Initialize a IPsecPolicyReference object.

        :param str id: The unique identifier for this IPsec policy.
        :param str href: The IPsec policy's canonical URL.
        :param str name: The user-defined name for this IPsec policy.
        :param str resource_type: The resource type.
        """
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyReference':
        """Initialize a IPsecPolicyReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in IPsecPolicyReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IPsecPolicyReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in IPsecPolicyReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in IPsecPolicyReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        IPSEC_POLICY = 'ipsec_policy'


class Image():
    """
    Image.

    :attr str id: The unique identifier for this image.
    :attr str crn: The CRN for this image.
    :attr str href: The URL for this image.
    :attr str name: The user-defined or system-provided name for this image.
    :attr int minimum_provisioned_size: (optional) The minimum size (in gigabytes)
          of a volume onto which this image may be provisioned.
          This property may be absent if the image has a `status` of `pending`,
          `tentative`, or
          `failed`.
    :attr ResourceGroupReference resource_group: The resource group for this image.
    :attr datetime created_at: The date and time that the image was created.
    :attr ImageFile file: Details for the stored image file.
    :attr OperatingSystem operating_system: (optional) The operating system included
          in this image.
    :attr str status: The status of this image.
    :attr str visibility: Whether the image is publicly visible or private to the
          account.
    """

    def __init__(self,
                 id: str,
                 crn: str,
                 href: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 created_at: datetime,
                 file: 'ImageFile',
                 status: str,
                 visibility: str,
                 *,
                 minimum_provisioned_size: int = None,
                 operating_system: 'OperatingSystem' = None) -> None:
        """
        Initialize a Image object.

        :param str id: The unique identifier for this image.
        :param str crn: The CRN for this image.
        :param str href: The URL for this image.
        :param str name: The user-defined or system-provided name for this image.
        :param ResourceGroupReference resource_group: The resource group for this
               image.
        :param datetime created_at: The date and time that the image was created.
        :param ImageFile file: Details for the stored image file.
        :param str status: The status of this image.
        :param str visibility: Whether the image is publicly visible or private to
               the account.
        :param int minimum_provisioned_size: (optional) The minimum size (in
               gigabytes) of a volume onto which this image may be provisioned.
               This property may be absent if the image has a `status` of `pending`,
               `tentative`, or
               `failed`.
        :param OperatingSystem operating_system: (optional) The operating system
               included in this image.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.minimum_provisioned_size = minimum_provisioned_size
        self.resource_group = resource_group
        self.created_at = created_at
        self.file = file
        self.operating_system = operating_system
        self.status = status
        self.visibility = visibility

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Image':
        """Initialize a Image object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Image JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Image JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Image JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Image JSON')
        if 'minimum_provisioned_size' in _dict:
            args['minimum_provisioned_size'] = _dict.get(
                'minimum_provisioned_size')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in Image JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in Image JSON')
        if 'file' in _dict:
            args['file'] = ImageFile.from_dict(_dict.get('file'))
        else:
            raise ValueError(
                'Required property \'file\' not present in Image JSON')
        if 'operating_system' in _dict:
            args['operating_system'] = OperatingSystem.from_dict(
                _dict.get('operating_system'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Image JSON')
        if 'visibility' in _dict:
            args['visibility'] = _dict.get('visibility')
        else:
            raise ValueError(
                'Required property \'visibility\' not present in Image JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Image object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'minimum_provisioned_size'
                  ) and self.minimum_provisioned_size is not None:
            _dict['minimum_provisioned_size'] = self.minimum_provisioned_size
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'file') and self.file is not None:
            _dict['file'] = self.file.to_dict()
        if hasattr(self,
                   'operating_system') and self.operating_system is not None:
            _dict['operating_system'] = self.operating_system.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'visibility') and self.visibility is not None:
            _dict['visibility'] = self.visibility
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Image object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Image') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Image') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of this image.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        DEPRECATED = 'deprecated'
        FAILED = 'failed'
        PENDING = 'pending'
        TENTATIVE = 'tentative'

    class VisibilityEnum(str, Enum):
        """
        Whether the image is publicly visible or private to the account.
        """
        PRIVATE = 'private'
        PUBLIC = 'public'


class ImageCollection():
    """
    ImageCollection.

    :attr ImageCollectionFirst first: A reference to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ImageCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr List[Image] images: Collection of images.
    """

    def __init__(self,
                 first: 'ImageCollectionFirst',
                 limit: int,
                 images: List['Image'],
                 *,
                 next: 'ImageCollectionNext' = None) -> None:
        """
        Initialize a ImageCollection object.

        :param ImageCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[Image] images: Collection of images.
        :param ImageCollectionNext next: (optional) A reference to the next page of
               resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.images = images

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageCollection':
        """Initialize a ImageCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ImageCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in ImageCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in ImageCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = ImageCollectionNext.from_dict(_dict.get('next'))
        if 'images' in _dict:
            args['images'] = [Image.from_dict(x) for x in _dict.get('images')]
        else:
            raise ValueError(
                'Required property \'images\' not present in ImageCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'images') and self.images is not None:
            _dict['images'] = [x.to_dict() for x in self.images]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ImageCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageCollectionFirst':
        """Initialize a ImageCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ImageCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ImageCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageCollectionNext':
        """Initialize a ImageCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ImageCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageFile():
    """
    ImageFile.

    :attr int size: (optional) The size of the stored image file rounded up to the
          next gigabyte.
          This property may be absent if the associated image has a `status` of `pending`
          or
          `failed`.
    """

    def __init__(self, *, size: int = None) -> None:
        """
        Initialize a ImageFile object.

        :param int size: (optional) The size of the stored image file rounded up to
               the next gigabyte.
               This property may be absent if the associated image has a `status` of
               `pending` or
               `failed`.
        """
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFile':
        """Initialize a ImageFile object from a json dictionary."""
        args = {}
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageFile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageFile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageFile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageFile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageFilePrototype():
    """
    ImageFilePrototype.

    :attr str href: The Cloud Object Store (COS) location of the image file.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ImageFilePrototype object.

        :param str href: The Cloud Object Store (COS) location of the image file.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFilePrototype':
        """Initialize a ImageFilePrototype object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ImageFilePrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageFilePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageFilePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageFilePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageFilePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageIdentity():
    """
    Identifies an image by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a ImageIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'ImageIdentityById', 'ImageIdentityByCRN', 'ImageIdentityByHref'
            ]))
        raise Exception(msg)


class ImagePrototype():
    """
    ImagePrototype.

    :attr str name: (optional) The unique user-defined name for this image. Names
          starting with "ibm-" are not allowed. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a ImagePrototype object.

        :param str name: (optional) The unique user-defined name for this image.
               Names starting with "ibm-" are not allowed. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ImagePrototypeImageByFile']))
        raise Exception(msg)


class ImageReference():
    """
    ImageReference.

    :attr str id: The unique identifier for this image.
    :attr str crn: The CRN for this image.
    :attr str href: The URL for this image.
    :attr str name: The user-defined or system-provided name for this image.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a ImageReference object.

        :param str id: The unique identifier for this image.
        :param str crn: The CRN for this image.
        :param str href: The URL for this image.
        :param str name: The user-defined or system-provided name for this image.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageReference':
        """Initialize a ImageReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ImageReference JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in ImageReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ImageReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ImageReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Instance():
    """
    Instance.

    :attr str id: The unique identifier for this virtual server instance.
    :attr str crn: The CRN for this virtual server instance.
    :attr str href: The URL for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    :attr ResourceGroupReference resource_group: The resource group for this
          instance.
    :attr int bandwidth: The total bandwidth (in megabits per second) shared across
          the virtual server instance's network interfaces.
    :attr VolumeAttachmentReferenceInstanceContext boot_volume_attachment: Boot
          volume attachment.
    :attr datetime created_at: The date and time that the virtual server instance
          was created.
    :attr InstanceGPU gpu: (optional) The virtual server instance GPU configuration.
    :attr ImageReference image: (optional) The image the virtual server instance was
          provisioned from.
    :attr int memory: The amount of memory in gigabytes.
    :attr List[NetworkInterfaceInstanceContextReference] network_interfaces:
          Collection of the virtual server instance's network interfaces, including the
          primary network interface.
    :attr NetworkInterfaceInstanceContextReference primary_network_interface:
          Primary network interface.
    :attr InstanceProfileReference profile: The profile this virtual server instance
          uses.
    :attr str status: The status of the virtual server instance.
    :attr InstanceVCPU vcpu: The virtual server instance VCPU configuration.
    :attr List[VolumeAttachmentReferenceInstanceContext] volume_attachments:
          Collection of the virtual server instance's volume attachments, including the
          boot volume attachment.
    :attr VPCReference vpc: The VPC the virtual server instance resides in.
    :attr ZoneReference zone: The zone the virtual server instance resides in.
    """

    def __init__(
            self,
            id: str,
            crn: str,
            href: str,
            name: str,
            resource_group: 'ResourceGroupReference',
            bandwidth: int,
            boot_volume_attachment: 'VolumeAttachmentReferenceInstanceContext',
            created_at: datetime,
            memory: int,
            network_interfaces: List[
                'NetworkInterfaceInstanceContextReference'],
            primary_network_interface:
        'NetworkInterfaceInstanceContextReference',
            profile: 'InstanceProfileReference',
            status: str,
            vcpu: 'InstanceVCPU',
            volume_attachments: List[
                'VolumeAttachmentReferenceInstanceContext'],
            vpc: 'VPCReference',
            zone: 'ZoneReference',
            *,
            gpu: 'InstanceGPU' = None,
            image: 'ImageReference' = None) -> None:
        """
        Initialize a Instance object.

        :param str id: The unique identifier for this virtual server instance.
        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        :param ResourceGroupReference resource_group: The resource group for this
               instance.
        :param int bandwidth: The total bandwidth (in megabits per second) shared
               across the virtual server instance's network interfaces.
        :param VolumeAttachmentReferenceInstanceContext boot_volume_attachment:
               Boot volume attachment.
        :param datetime created_at: The date and time that the virtual server
               instance was created.
        :param int memory: The amount of memory in gigabytes.
        :param List[NetworkInterfaceInstanceContextReference] network_interfaces:
               Collection of the virtual server instance's network interfaces, including
               the primary network interface.
        :param NetworkInterfaceInstanceContextReference primary_network_interface:
               Primary network interface.
        :param InstanceProfileReference profile: The profile this virtual server
               instance uses.
        :param str status: The status of the virtual server instance.
        :param InstanceVCPU vcpu: The virtual server instance VCPU configuration.
        :param List[VolumeAttachmentReferenceInstanceContext] volume_attachments:
               Collection of the virtual server instance's volume attachments, including
               the boot volume attachment.
        :param VPCReference vpc: The VPC the virtual server instance resides in.
        :param ZoneReference zone: The zone the virtual server instance resides in.
        :param InstanceGPU gpu: (optional) The virtual server instance GPU
               configuration.
        :param ImageReference image: (optional) The image the virtual server
               instance was provisioned from.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_group = resource_group
        self.bandwidth = bandwidth
        self.boot_volume_attachment = boot_volume_attachment
        self.created_at = created_at
        self.gpu = gpu
        self.image = image
        self.memory = memory
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.profile = profile
        self.status = status
        self.vcpu = vcpu
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Instance':
        """Initialize a Instance object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Instance JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Instance JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Instance JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Instance JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in Instance JSON'
            )
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError(
                'Required property \'bandwidth\' not present in Instance JSON')
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentReferenceInstanceContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        else:
            raise ValueError(
                'Required property \'boot_volume_attachment\' not present in Instance JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in Instance JSON')
        if 'gpu' in _dict:
            args['gpu'] = InstanceGPU.from_dict(_dict.get('gpu'))
        if 'image' in _dict:
            args['image'] = ImageReference.from_dict(_dict.get('image'))
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError(
                'Required property \'memory\' not present in Instance JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfaceInstanceContextReference.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        else:
            raise ValueError(
                'Required property \'network_interfaces\' not present in Instance JSON'
            )
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfaceInstanceContextReference.from_dict(
                    _dict.get('primary_network_interface'))
        else:
            raise ValueError(
                'Required property \'primary_network_interface\' not present in Instance JSON'
            )
        if 'profile' in _dict:
            args['profile'] = InstanceProfileReference.from_dict(
                _dict.get('profile'))
        else:
            raise ValueError(
                'Required property \'profile\' not present in Instance JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Instance JSON')
        if 'vcpu' in _dict:
            args['vcpu'] = InstanceVCPU.from_dict(_dict.get('vcpu'))
        else:
            raise ValueError(
                'Required property \'vcpu\' not present in Instance JSON')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentReferenceInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        else:
            raise ValueError(
                'Required property \'volume_attachments\' not present in Instance JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in Instance JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in Instance JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Instance object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'bandwidth') and self.bandwidth is not None:
            _dict['bandwidth'] = self.bandwidth
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'gpu') and self.gpu is not None:
            _dict['gpu'] = self.gpu.to_dict()
        if hasattr(self, 'image') and self.image is not None:
            _dict['image'] = self.image.to_dict()
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'profile') and self.profile is not None:
            _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'vcpu') and self.vcpu is not None:
            _dict['vcpu'] = self.vcpu.to_dict()
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Instance object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Instance') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Instance') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the virtual server instance.
        """
        FAILED = 'failed'
        PAUSED = 'paused'
        PAUSING = 'pausing'
        PENDING = 'pending'
        RESTARTING = 'restarting'
        RESUMING = 'resuming'
        RUNNING = 'running'
        STARTING = 'starting'
        STOPPED = 'stopped'
        STOPPING = 'stopping'


class InstanceAction():
    """
    InstanceAction.

    :attr str id: The identifier for this instance action.
    :attr str href: The URL for this instance action.
    :attr bool force: (optional) If set to true, the action will be forced
          immediately, and all queued actions deleted. Ignored for the start action.
    :attr str type: The type of action.
    :attr datetime completed_at: (optional) The date and time that the action was
          completed.
    :attr datetime created_at: The date and time that the action was created.
    :attr datetime started_at: (optional) The date and time that the action was
          started.
    :attr str status: The current status of this action.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 type: str,
                 created_at: datetime,
                 status: str,
                 *,
                 force: bool = None,
                 completed_at: datetime = None,
                 started_at: datetime = None) -> None:
        """
        Initialize a InstanceAction object.

        :param str id: The identifier for this instance action.
        :param str href: The URL for this instance action.
        :param str type: The type of action.
        :param datetime created_at: The date and time that the action was created.
        :param str status: The current status of this action.
        :param bool force: (optional) If set to true, the action will be forced
               immediately, and all queued actions deleted. Ignored for the start action.
        :param datetime completed_at: (optional) The date and time that the action
               was completed.
        :param datetime started_at: (optional) The date and time that the action
               was started.
        """
        self.id = id
        self.href = href
        self.force = force
        self.type = type
        self.completed_at = completed_at
        self.created_at = created_at
        self.started_at = started_at
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceAction':
        """Initialize a InstanceAction object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceAction JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceAction JSON')
        if 'force' in _dict:
            args['force'] = _dict.get('force')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceAction JSON')
        if 'completed_at' in _dict:
            args['completed_at'] = string_to_datetime(_dict.get('completed_at'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in InstanceAction JSON'
            )
        if 'started_at' in _dict:
            args['started_at'] = string_to_datetime(_dict.get('started_at'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in InstanceAction JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceAction object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'force') and self.force is not None:
            _dict['force'] = self.force
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'completed_at') and self.completed_at is not None:
            _dict['completed_at'] = datetime_to_string(self.completed_at)
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'started_at') and self.started_at is not None:
            _dict['started_at'] = datetime_to_string(self.started_at)
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceAction object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceAction') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceAction') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of action.
        """
        REBOOT = 'reboot'
        START = 'start'
        STOP = 'stop'

    class StatusEnum(str, Enum):
        """
        The current status of this action.
        """
        COMPLETED = 'completed'
        FAILED = 'failed'
        PENDING = 'pending'
        RUNNING = 'running'


class InstanceCollection():
    """
    InstanceCollection.

    :attr InstanceCollectionFirst first: A reference to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[Instance] instances: Collection of virtual server instances.
    """

    def __init__(self,
                 first: 'InstanceCollectionFirst',
                 limit: int,
                 total_count: int,
                 instances: List['Instance'],
                 *,
                 next: 'InstanceCollectionNext' = None) -> None:
        """
        Initialize a InstanceCollection object.

        :param InstanceCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[Instance] instances: Collection of virtual server instances.
        :param InstanceCollectionNext next: (optional) A reference to the next page
               of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.instances = instances

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCollection':
        """Initialize a InstanceCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in InstanceCollection JSON'
            )
        if 'instances' in _dict:
            args['instances'] = [
                Instance.from_dict(x) for x in _dict.get('instances')
            ]
        else:
            raise ValueError(
                'Required property \'instances\' not present in InstanceCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'instances') and self.instances is not None:
            _dict['instances'] = [x.to_dict() for x in self.instances]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCollectionFirst':
        """Initialize a InstanceCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCollectionNext':
        """Initialize a InstanceCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGPU():
    """
    The virtual server instance GPU configuration.

    :attr int count: The number of GPUs assigned to the instance.
    :attr str manufacturer: The GPU manufacturer.
    :attr int memory: The overall amount of GPU memory in GiB (gibibytes).
    :attr str model: The GPU model.
    """

    def __init__(self, count: int, manufacturer: str, memory: int,
                 model: str) -> None:
        """
        Initialize a InstanceGPU object.

        :param int count: The number of GPUs assigned to the instance.
        :param str manufacturer: The GPU manufacturer.
        :param int memory: The overall amount of GPU memory in GiB (gibibytes).
        :param str model: The GPU model.
        """
        self.count = count
        self.manufacturer = manufacturer
        self.memory = memory
        self.model = model

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGPU':
        """Initialize a InstanceGPU object from a json dictionary."""
        args = {}
        if 'count' in _dict:
            args['count'] = _dict.get('count')
        else:
            raise ValueError(
                'Required property \'count\' not present in InstanceGPU JSON')
        if 'manufacturer' in _dict:
            args['manufacturer'] = _dict.get('manufacturer')
        else:
            raise ValueError(
                'Required property \'manufacturer\' not present in InstanceGPU JSON'
            )
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError(
                'Required property \'memory\' not present in InstanceGPU JSON')
        if 'model' in _dict:
            args['model'] = _dict.get('model')
        else:
            raise ValueError(
                'Required property \'model\' not present in InstanceGPU JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGPU object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'count') and self.count is not None:
            _dict['count'] = self.count
        if hasattr(self, 'manufacturer') and self.manufacturer is not None:
            _dict['manufacturer'] = self.manufacturer
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(self, 'model') and self.model is not None:
            _dict['model'] = self.model
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGPU object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGPU') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGPU') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroup():
    """
    InstanceGroup.

    :attr str id: The unique identifier for this instance group.
    :attr str crn: The CRN for this instance group.
    :attr str href: The URL for this instance group.
    :attr str name: The user-defined name for this instance group.
    :attr int membership_count: The number of instances in the instance group.
    :attr int application_port: (optional) Required if specifying a load balancer
          pool only. Used by the instance group when scaling up instances to supply the
          port for the load balancer pool member.
    :attr LoadBalancerPoolReference load_balancer_pool: (optional) The load balancer
          pool managed by this group. Instances created
          by this group will have a new load balancer pool member in that
          pool created.
    :attr datetime created_at: The date and time that the instance group was
          created.
    :attr InstanceTemplateReference instance_template: The template used to create
          new instances for this group.
    :attr List[InstanceGroupManagerReference] managers: Array of references to
          managers for the instance group.
    :attr ResourceGroupReference resource_group:
    :attr str status: The status of the instance group
          - `deleting`: Group is being deleted
          - `healthy`: Group has `membership_count` instances
          - `scaling`: Instances in the group are being created or deleted to reach
                       `membership_count`
          - `unhealthy`: Group is unable to reach `membership_count` instances.
    :attr List[SubnetReference] subnets: Array of references to subnets to use when
          creating new instances.
    :attr VPCReference vpc: The VPC the instance group resides in.
    """

    def __init__(
            self,
            id: str,
            crn: str,
            href: str,
            name: str,
            membership_count: int,
            created_at: datetime,
            instance_template: 'InstanceTemplateReference',
            managers: List['InstanceGroupManagerReference'],
            resource_group: 'ResourceGroupReference',
            status: str,
            subnets: List['SubnetReference'],
            vpc: 'VPCReference',
            *,
            application_port: int = None,
            load_balancer_pool: 'LoadBalancerPoolReference' = None) -> None:
        """
        Initialize a InstanceGroup object.

        :param str id: The unique identifier for this instance group.
        :param str crn: The CRN for this instance group.
        :param str href: The URL for this instance group.
        :param str name: The user-defined name for this instance group.
        :param int membership_count: The number of instances in the instance group.
        :param datetime created_at: The date and time that the instance group was
               created.
        :param InstanceTemplateReference instance_template: The template used to
               create new instances for this group.
        :param List[InstanceGroupManagerReference] managers: Array of references to
               managers for the instance group.
        :param ResourceGroupReference resource_group:
        :param str status: The status of the instance group
               - `deleting`: Group is being deleted
               - `healthy`: Group has `membership_count` instances
               - `scaling`: Instances in the group are being created or deleted to reach
                            `membership_count`
               - `unhealthy`: Group is unable to reach `membership_count` instances.
        :param List[SubnetReference] subnets: Array of references to subnets to use
               when creating new instances.
        :param VPCReference vpc: The VPC the instance group resides in.
        :param int application_port: (optional) Required if specifying a load
               balancer pool only. Used by the instance group when scaling up instances to
               supply the port for the load balancer pool member.
        :param LoadBalancerPoolReference load_balancer_pool: (optional) The load
               balancer pool managed by this group. Instances created
               by this group will have a new load balancer pool member in that
               pool created.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.membership_count = membership_count
        self.application_port = application_port
        self.load_balancer_pool = load_balancer_pool
        self.created_at = created_at
        self.instance_template = instance_template
        self.managers = managers
        self.resource_group = resource_group
        self.status = status
        self.subnets = subnets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroup':
        """Initialize a InstanceGroup object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroup JSON')
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError(
                'Required property \'membership_count\' not present in InstanceGroup JSON'
            )
        if 'application_port' in _dict:
            args['application_port'] = _dict.get('application_port')
        if 'load_balancer_pool' in _dict:
            args['load_balancer_pool'] = LoadBalancerPoolReference.from_dict(
                _dict.get('load_balancer_pool'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in InstanceGroup JSON'
            )
        if 'instance_template' in _dict:
            args['instance_template'] = InstanceTemplateReference.from_dict(
                _dict.get('instance_template'))
        else:
            raise ValueError(
                'Required property \'instance_template\' not present in InstanceGroup JSON'
            )
        if 'managers' in _dict:
            args['managers'] = [
                InstanceGroupManagerReference.from_dict(x)
                for x in _dict.get('managers')
            ]
        else:
            raise ValueError(
                'Required property \'managers\' not present in InstanceGroup JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in InstanceGroup JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in InstanceGroup JSON'
            )
        if 'subnets' in _dict:
            args['subnets'] = [
                SubnetReference.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in InstanceGroup JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in InstanceGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self,
                   'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        if hasattr(self,
                   'application_port') and self.application_port is not None:
            _dict['application_port'] = self.application_port
        if hasattr(
                self,
                'load_balancer_pool') and self.load_balancer_pool is not None:
            _dict['load_balancer_pool'] = self.load_balancer_pool.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self,
                   'instance_template') and self.instance_template is not None:
            _dict['instance_template'] = self.instance_template.to_dict()
        if hasattr(self, 'managers') and self.managers is not None:
            _dict['managers'] = [x.to_dict() for x in self.managers]
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'subnets') and self.subnets is not None:
            _dict['subnets'] = [x.to_dict() for x in self.subnets]
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the instance group
        - `deleting`: Group is being deleted
        - `healthy`: Group has `membership_count` instances
        - `scaling`: Instances in the group are being created or deleted to reach
                     `membership_count`
        - `unhealthy`: Group is unable to reach `membership_count` instances.
        """
        DELETING = 'deleting'
        HEALTHY = 'healthy'
        SCALING = 'scaling'
        UNHEALTHY = 'unhealthy'


class InstanceGroupCollection():
    """
    InstanceGroupCollection.

    :attr InstanceGroupCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[InstanceGroup] instance_groups: Collection of instance groups.
    """

    def __init__(self,
                 first: 'InstanceGroupCollectionFirst',
                 limit: int,
                 total_count: int,
                 instance_groups: List['InstanceGroup'],
                 *,
                 next: 'InstanceGroupCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupCollection object.

        :param InstanceGroupCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[InstanceGroup] instance_groups: Collection of instance groups.
        :param InstanceGroupCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.instance_groups = instance_groups

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupCollection':
        """Initialize a InstanceGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceGroupCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceGroupCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceGroupCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in InstanceGroupCollection JSON'
            )
        if 'instance_groups' in _dict:
            args['instance_groups'] = [
                InstanceGroup.from_dict(x) for x in _dict.get('instance_groups')
            ]
        else:
            raise ValueError(
                'Required property \'instance_groups\' not present in InstanceGroupCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self,
                   'instance_groups') and self.instance_groups is not None:
            _dict['instance_groups'] = [
                x.to_dict() for x in self.instance_groups
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupCollectionFirst':
        """Initialize a InstanceGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupCollectionNext':
        """Initialize a InstanceGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManager():
    """
    InstanceGroupManager.

    :attr str id: The unique identifier for this instance group manager.
    :attr str href: The URL for this instance group manager.
    :attr str name: The user-defined name for this instance group manager. Names
          must be unique within the instance group.
    :attr bool management_enabled: If set to `true`, this manager will control the
          instance group.
    :attr int aggregation_window: (optional) The time window in seconds to aggregate
          metrics prior to evaluation.
    :attr int cooldown: (optional) The duration of time in seconds to pause further
          scale actions after scaling has taken place.
    :attr int max_membership_count: (optional) The maximum number of members in a
          managed instance group.
    :attr int min_membership_count: (optional) The minimum number of members in a
          managed instance group.
    :attr str manager_type: The type of instance group manager.
    :attr List[InstanceGroupManagerPolicyReference] policies: The policies of the
          instance group manager.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 management_enabled: bool,
                 manager_type: str,
                 policies: List['InstanceGroupManagerPolicyReference'],
                 *,
                 aggregation_window: int = None,
                 cooldown: int = None,
                 max_membership_count: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManager object.

        :param str id: The unique identifier for this instance group manager.
        :param str href: The URL for this instance group manager.
        :param str name: The user-defined name for this instance group manager.
               Names must be unique within the instance group.
        :param bool management_enabled: If set to `true`, this manager will control
               the instance group.
        :param str manager_type: The type of instance group manager.
        :param List[InstanceGroupManagerPolicyReference] policies: The policies of
               the instance group manager.
        :param int aggregation_window: (optional) The time window in seconds to
               aggregate metrics prior to evaluation.
        :param int cooldown: (optional) The duration of time in seconds to pause
               further scale actions after scaling has taken place.
        :param int max_membership_count: (optional) The maximum number of members
               in a managed instance group.
        :param int min_membership_count: (optional) The minimum number of members
               in a managed instance group.
        """
        self.id = id
        self.href = href
        self.name = name
        self.management_enabled = management_enabled
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.manager_type = manager_type
        self.policies = policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManager':
        """Initialize a InstanceGroupManager object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManager JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManager JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManager JSON'
            )
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        else:
            raise ValueError(
                'Required property \'management_enabled\' not present in InstanceGroupManager JSON'
            )
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError(
                'Required property \'manager_type\' not present in InstanceGroupManager JSON'
            )
        if 'policies' in _dict:
            args['policies'] = [
                InstanceGroupManagerPolicyReference.from_dict(x)
                for x in _dict.get('policies')
            ]
        else:
            raise ValueError(
                'Required property \'policies\' not present in InstanceGroupManager JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManager object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(
                self,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(
                self,
                'aggregation_window') and self.aggregation_window is not None:
            _dict['aggregation_window'] = self.aggregation_window
        if hasattr(self, 'cooldown') and self.cooldown is not None:
            _dict['cooldown'] = self.cooldown
        if hasattr(self, 'max_membership_count'
                  ) and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count'
                  ) and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        if hasattr(self, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        if hasattr(self, 'policies') and self.policies is not None:
            _dict['policies'] = [x.to_dict() for x in self.policies]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManager object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManager') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManager') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ManagerTypeEnum(str, Enum):
        """
        The type of instance group manager.
        """
        AUTOSCALE = 'autoscale'


class InstanceGroupManagerCollection():
    """
    InstanceGroupManagerCollection.

    :attr InstanceGroupManagerCollectionFirst first: A reference to the first page
          of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupManagerCollectionNext next: (optional) A reference to the
          next page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[InstanceGroupManager] managers: Collection of instance group
          managers.
    """

    def __init__(self,
                 first: 'InstanceGroupManagerCollectionFirst',
                 limit: int,
                 total_count: int,
                 managers: List['InstanceGroupManager'],
                 *,
                 next: 'InstanceGroupManagerCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupManagerCollection object.

        :param InstanceGroupManagerCollectionFirst first: A reference to the first
               page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[InstanceGroupManager] managers: Collection of instance group
               managers.
        :param InstanceGroupManagerCollectionNext next: (optional) A reference to
               the next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.managers = managers

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerCollection':
        """Initialize a InstanceGroupManagerCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupManagerCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceGroupManagerCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceGroupManagerCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceGroupManagerCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in InstanceGroupManagerCollection JSON'
            )
        if 'managers' in _dict:
            args['managers'] = [
                InstanceGroupManager.from_dict(x) for x in _dict.get('managers')
            ]
        else:
            raise ValueError(
                'Required property \'managers\' not present in InstanceGroupManagerCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'managers') and self.managers is not None:
            _dict['managers'] = [x.to_dict() for x in self.managers]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerCollectionFirst':
        """Initialize a InstanceGroupManagerCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerCollectionNext':
        """Initialize a InstanceGroupManagerCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicy():
    """
    InstanceGroupManagerPolicy.

    :attr str id: The unique identifier for this instance group manager policy.
    :attr str href: The URL for this instance group manager policy.
    :attr str name: The user-defined name for this instance group manager policy.
          Names must be unique within the instance group manager.
    """

    def __init__(self, id: str, href: str, name: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicy object.

        :param str id: The unique identifier for this instance group manager
               policy.
        :param str href: The URL for this instance group manager policy.
        :param str name: The user-defined name for this instance group manager
               policy. Names must be unique within the instance group manager.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(
                ['InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy']))
        raise Exception(msg)


class InstanceGroupManagerPolicyCollection():
    """
    InstanceGroupManagerPolicyCollection.

    :attr InstanceGroupManagerPolicyCollectionFirst first: A reference to the first
          page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupManagerPolicyCollectionNext next: (optional) A reference to
          the next page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[InstanceGroupManagerPolicy] policies: Collection of instance group
          manager policies.
    """

    def __init__(
            self,
            first: 'InstanceGroupManagerPolicyCollectionFirst',
            limit: int,
            total_count: int,
            policies: List['InstanceGroupManagerPolicy'],
            *,
            next: 'InstanceGroupManagerPolicyCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollection object.

        :param InstanceGroupManagerPolicyCollectionFirst first: A reference to the
               first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[InstanceGroupManagerPolicy] policies: Collection of instance
               group manager policies.
        :param InstanceGroupManagerPolicyCollectionNext next: (optional) A
               reference to the next page of resources; this reference is included for all
               pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.policies = policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyCollection':
        """Initialize a InstanceGroupManagerPolicyCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupManagerPolicyCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceGroupManagerPolicyCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceGroupManagerPolicyCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceGroupManagerPolicyCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in InstanceGroupManagerPolicyCollection JSON'
            )
        if 'policies' in _dict:
            args['policies'] = _dict.get('policies')
        else:
            raise ValueError(
                'Required property \'policies\' not present in InstanceGroupManagerPolicyCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'policies') and self.policies is not None:
            policies_list = []
            for x in self.policies:
                if isinstance(x, dict):
                    policies_list.append(x)
                else:
                    policies_list.append(x.to_dict())
            _dict['policies'] = policies_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceGroupManagerPolicyCollectionFirst':
        """Initialize a InstanceGroupManagerPolicyCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerPolicyCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceGroupManagerPolicyCollectionNext':
        """Initialize a InstanceGroupManagerPolicyCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerPolicyCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyPrototype():
    """
    InstanceGroupManagerPolicyPrototype.

    :attr str name: (optional) The user-defined name for this instance group manager
          policy. Names must be unique within the instance group manager.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerPolicyPrototype object.

        :param str name: (optional) The user-defined name for this instance group
               manager policy. Names must be unique within the instance group manager.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype'
            ]))
        raise Exception(msg)


class InstanceGroupManagerPolicyReference():
    """
    InstanceGroupManagerPolicyReference.

    :attr str id: The unique identifier for this instance group manager policy.
    :attr str href: The URL for this instance group manager policy.
    :attr str name: The user-defined name for this instance group manager policy.
          Names must be unique within the instance group manager.
    """

    def __init__(self, id: str, href: str, name: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyReference object.

        :param str id: The unique identifier for this instance group manager
               policy.
        :param str href: The URL for this instance group manager policy.
        :param str name: The user-defined name for this instance group manager
               policy. Names must be unique within the instance group manager.
        """
        self.id = id
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyReference':
        """Initialize a InstanceGroupManagerPolicyReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerPolicyReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerPolicyReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerPolicyReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPrototype():
    """
    InstanceGroupManagerPrototype.

    :attr str name: (optional) The user-defined name for this instance group
          manager. Names must be unique within the instance group.
    :attr bool management_enabled: (optional) If set to `true`, this manager will
          control the instance group.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 management_enabled: bool = None) -> None:
        """
        Initialize a InstanceGroupManagerPrototype object.

        :param str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within the instance group.
        :param bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype'
            ]))
        raise Exception(msg)


class InstanceGroupManagerReference():
    """
    InstanceGroupManagerReference.

    :attr str id: The unique identifier for this instance group manager.
    :attr str href: The URL for this instance group manager.
    :attr str name: The user-defined name for this instance group manager. Names
          must be unique within the instance group.
    """

    def __init__(self, id: str, href: str, name: str) -> None:
        """
        Initialize a InstanceGroupManagerReference object.

        :param str id: The unique identifier for this instance group manager.
        :param str href: The URL for this instance group manager.
        :param str name: The user-defined name for this instance group manager.
               Names must be unique within the instance group.
        """
        self.id = id
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerReference':
        """Initialize a InstanceGroupManagerReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupMembership():
    """
    InstanceGroupMembership.

    :attr str id: The unique identifier for this instance group membership.
    :attr str href: The URL for this instance group membership.
    :attr str name: The user-defined name for this instance group membership. Names
          must be unique within the instance group.
    :attr bool delete_instance_on_membership_delete: If set to true, when deleting
          the membership the instance will also be deleted.
    :attr InstanceReference instance:
    :attr InstanceTemplateReference instance_template:
    :attr LoadBalancerPoolMemberReference pool_member: (optional)
    :attr str status: The status of the instance group membership
          - `deleting`: Membership is deleting dependent resources
          - `failed`: Membership was unable to maintain dependent resources
          - `healthy`: Membership is active and serving in the group
          - `pending`: Membership is waiting for dependent resources
          - `unhealthy`: Membership has unhealthy dependent resources.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 delete_instance_on_membership_delete: bool,
                 instance: 'InstanceReference',
                 instance_template: 'InstanceTemplateReference',
                 status: str,
                 *,
                 pool_member: 'LoadBalancerPoolMemberReference' = None) -> None:
        """
        Initialize a InstanceGroupMembership object.

        :param str id: The unique identifier for this instance group membership.
        :param str href: The URL for this instance group membership.
        :param str name: The user-defined name for this instance group membership.
               Names must be unique within the instance group.
        :param bool delete_instance_on_membership_delete: If set to true, when
               deleting the membership the instance will also be deleted.
        :param InstanceReference instance:
        :param InstanceTemplateReference instance_template:
        :param str status: The status of the instance group membership
               - `deleting`: Membership is deleting dependent resources
               - `failed`: Membership was unable to maintain dependent resources
               - `healthy`: Membership is active and serving in the group
               - `pending`: Membership is waiting for dependent resources
               - `unhealthy`: Membership has unhealthy dependent resources.
        :param LoadBalancerPoolMemberReference pool_member: (optional)
        """
        self.id = id
        self.href = href
        self.name = name
        self.delete_instance_on_membership_delete = delete_instance_on_membership_delete
        self.instance = instance
        self.instance_template = instance_template
        self.pool_member = pool_member
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembership':
        """Initialize a InstanceGroupMembership object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupMembership JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupMembership JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupMembership JSON'
            )
        if 'delete_instance_on_membership_delete' in _dict:
            args['delete_instance_on_membership_delete'] = _dict.get(
                'delete_instance_on_membership_delete')
        else:
            raise ValueError(
                'Required property \'delete_instance_on_membership_delete\' not present in InstanceGroupMembership JSON'
            )
        if 'instance' in _dict:
            args['instance'] = InstanceReference.from_dict(
                _dict.get('instance'))
        else:
            raise ValueError(
                'Required property \'instance\' not present in InstanceGroupMembership JSON'
            )
        if 'instance_template' in _dict:
            args['instance_template'] = InstanceTemplateReference.from_dict(
                _dict.get('instance_template'))
        else:
            raise ValueError(
                'Required property \'instance_template\' not present in InstanceGroupMembership JSON'
            )
        if 'pool_member' in _dict:
            args['pool_member'] = LoadBalancerPoolMemberReference.from_dict(
                _dict.get('pool_member'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in InstanceGroupMembership JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembership object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'delete_instance_on_membership_delete'
                  ) and self.delete_instance_on_membership_delete is not None:
            _dict[
                'delete_instance_on_membership_delete'] = self.delete_instance_on_membership_delete
        if hasattr(self, 'instance') and self.instance is not None:
            _dict['instance'] = self.instance.to_dict()
        if hasattr(self,
                   'instance_template') and self.instance_template is not None:
            _dict['instance_template'] = self.instance_template.to_dict()
        if hasattr(self, 'pool_member') and self.pool_member is not None:
            _dict['pool_member'] = self.pool_member.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembership object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembership') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembership') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the instance group membership
        - `deleting`: Membership is deleting dependent resources
        - `failed`: Membership was unable to maintain dependent resources
        - `healthy`: Membership is active and serving in the group
        - `pending`: Membership is waiting for dependent resources
        - `unhealthy`: Membership has unhealthy dependent resources.
        """
        DELETING = 'deleting'
        FAILED = 'failed'
        HEALTHY = 'healthy'
        PENDING = 'pending'
        UNHEALTHY = 'unhealthy'


class InstanceGroupMembershipCollection():
    """
    InstanceGroupMembershipCollection.

    :attr InstanceGroupMembershipCollectionFirst first: A reference to the first
          page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupMembershipCollectionNext next: (optional) A reference to the
          next page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[InstanceGroupMembership] memberships: Collection of instance group
          memberships.
    """

    def __init__(self,
                 first: 'InstanceGroupMembershipCollectionFirst',
                 limit: int,
                 total_count: int,
                 memberships: List['InstanceGroupMembership'],
                 *,
                 next: 'InstanceGroupMembershipCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupMembershipCollection object.

        :param InstanceGroupMembershipCollectionFirst first: A reference to the
               first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[InstanceGroupMembership] memberships: Collection of instance
               group memberships.
        :param InstanceGroupMembershipCollectionNext next: (optional) A reference
               to the next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.memberships = memberships

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipCollection':
        """Initialize a InstanceGroupMembershipCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupMembershipCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceGroupMembershipCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceGroupMembershipCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceGroupMembershipCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in InstanceGroupMembershipCollection JSON'
            )
        if 'memberships' in _dict:
            args['memberships'] = [
                InstanceGroupMembership.from_dict(x)
                for x in _dict.get('memberships')
            ]
        else:
            raise ValueError(
                'Required property \'memberships\' not present in InstanceGroupMembershipCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'memberships') and self.memberships is not None:
            _dict['memberships'] = [x.to_dict() for x in self.memberships]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupMembershipCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupMembershipCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipCollectionFirst':
        """Initialize a InstanceGroupMembershipCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupMembershipCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupMembershipCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupMembershipCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipCollectionNext':
        """Initialize a InstanceGroupMembershipCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupMembershipCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupReference():
    """
    InstanceGroupReference.

    :attr str id: The unique identifier for this instance group.
    :attr str crn: The CRN for this instance group.
    :attr str href: The URL for this instance group.
    :attr str name: The user-defined name for this instance group.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a InstanceGroupReference object.

        :param str id: The unique identifier for this instance group.
        :param str crn: The CRN for this instance group.
        :param str href: The URL for this instance group.
        :param str name: The user-defined name for this instance group.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupReference':
        """Initialize a InstanceGroupReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceGroupReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceInitialization():
    """
    InstanceInitialization.

    :attr List[KeyReferenceInstanceInitializationContext] keys: Collection of
          references to public SSH keys used at instance initialization.
    :attr InstanceInitializationPassword password: (optional)
    """

    def __init__(self,
                 keys: List['KeyReferenceInstanceInitializationContext'],
                 *,
                 password: 'InstanceInitializationPassword' = None) -> None:
        """
        Initialize a InstanceInitialization object.

        :param List[KeyReferenceInstanceInitializationContext] keys: Collection of
               references to public SSH keys used at instance initialization.
        :param InstanceInitializationPassword password: (optional)
        """
        self.keys = keys
        self.password = password

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceInitialization':
        """Initialize a InstanceInitialization object from a json dictionary."""
        args = {}
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        else:
            raise ValueError(
                'Required property \'keys\' not present in InstanceInitialization JSON'
            )
        if 'password' in _dict:
            args['password'] = InstanceInitializationPassword.from_dict(
                _dict.get('password'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceInitialization object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'password') and self.password is not None:
            _dict['password'] = self.password.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceInitialization object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceInitialization') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceInitialization') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceInitializationPassword():
    """
    InstanceInitializationPassword.

    :attr bytes encrypted_password: The administrator password at initialization,
          encrypted using `encryption_key`, and returned base64-encoded.
    :attr KeyReferenceInstanceInitializationContext encryption_key: The reference to
          the public SSH key used to encrypt the administrator password.
    """

    def __init__(
            self, encrypted_password: bytes,
            encryption_key: 'KeyReferenceInstanceInitializationContext'
    ) -> None:
        """
        Initialize a InstanceInitializationPassword object.

        :param bytes encrypted_password: The administrator password at
               initialization, encrypted using `encryption_key`, and returned
               base64-encoded.
        :param KeyReferenceInstanceInitializationContext encryption_key: The
               reference to the public SSH key used to encrypt the administrator password.
        """
        self.encrypted_password = encrypted_password
        self.encryption_key = encryption_key

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceInitializationPassword':
        """Initialize a InstanceInitializationPassword object from a json dictionary."""
        args = {}
        if 'encrypted_password' in _dict:
            args['encrypted_password'] = base64.b64decode(
                _dict.get('encrypted_password'))
        else:
            raise ValueError(
                'Required property \'encrypted_password\' not present in InstanceInitializationPassword JSON'
            )
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        else:
            raise ValueError(
                'Required property \'encryption_key\' not present in InstanceInitializationPassword JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceInitializationPassword object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(
                self,
                'encrypted_password') and self.encrypted_password is not None:
            _dict['encrypted_password'] = str(
                base64.b64encode(self.encrypted_password), 'utf-8')
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceInitializationPassword object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceInitializationPassword') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceInitializationPassword') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfile():
    """
    InstanceProfile.

    :attr str name: The name for this virtual server instance profile.
    :attr str href: The URL for this virtual server instance profile.
    :attr InstanceProfileBandwidth bandwidth:
    :attr InstanceProfilePortSpeed port_speed:
    :attr InstanceProfileMemory memory:
    :attr InstanceProfileOSArchitecture os_architecture:
    :attr InstanceProfileVCPUArchitecture vcpu_architecture:
    :attr InstanceProfileVCPU vcpu_count:
    :attr str family: (optional) The product family this virtual server instance
          profile belongs to.
    """

    def __init__(self,
                 name: str,
                 href: str,
                 bandwidth: 'InstanceProfileBandwidth',
                 port_speed: 'InstanceProfilePortSpeed',
                 memory: 'InstanceProfileMemory',
                 os_architecture: 'InstanceProfileOSArchitecture',
                 vcpu_architecture: 'InstanceProfileVCPUArchitecture',
                 vcpu_count: 'InstanceProfileVCPU',
                 *,
                 family: str = None) -> None:
        """
        Initialize a InstanceProfile object.

        :param str name: The name for this virtual server instance profile.
        :param str href: The URL for this virtual server instance profile.
        :param InstanceProfileBandwidth bandwidth:
        :param InstanceProfilePortSpeed port_speed:
        :param InstanceProfileMemory memory:
        :param InstanceProfileOSArchitecture os_architecture:
        :param InstanceProfileVCPUArchitecture vcpu_architecture:
        :param InstanceProfileVCPU vcpu_count:
        :param str family: (optional) The product family this virtual server
               instance profile belongs to.
        """
        self.name = name
        self.href = href
        self.bandwidth = bandwidth
        self.port_speed = port_speed
        self.memory = memory
        self.os_architecture = os_architecture
        self.vcpu_architecture = vcpu_architecture
        self.vcpu_count = vcpu_count
        self.family = family

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfile':
        """Initialize a InstanceProfile object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceProfile JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceProfile JSON'
            )
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError(
                'Required property \'bandwidth\' not present in InstanceProfile JSON'
            )
        if 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError(
                'Required property \'port_speed\' not present in InstanceProfile JSON'
            )
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError(
                'Required property \'memory\' not present in InstanceProfile JSON'
            )
        if 'os_architecture' in _dict:
            args['os_architecture'] = InstanceProfileOSArchitecture.from_dict(
                _dict.get('os_architecture'))
        else:
            raise ValueError(
                'Required property \'os_architecture\' not present in InstanceProfile JSON'
            )
        if 'vcpu_architecture' in _dict:
            args[
                'vcpu_architecture'] = InstanceProfileVCPUArchitecture.from_dict(
                    _dict.get('vcpu_architecture'))
        else:
            raise ValueError(
                'Required property \'vcpu_architecture\' not present in InstanceProfile JSON'
            )
        if 'vcpu_count' in _dict:
            args['vcpu_count'] = _dict.get('vcpu_count')
        else:
            raise ValueError(
                'Required property \'vcpu_count\' not present in InstanceProfile JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'bandwidth') and self.bandwidth is not None:
            if isinstance(self.bandwidth, dict):
                _dict['bandwidth'] = self.bandwidth
            else:
                _dict['bandwidth'] = self.bandwidth.to_dict()
        if hasattr(self, 'port_speed') and self.port_speed is not None:
            if isinstance(self.port_speed, dict):
                _dict['port_speed'] = self.port_speed
            else:
                _dict['port_speed'] = self.port_speed.to_dict()
        if hasattr(self, 'memory') and self.memory is not None:
            if isinstance(self.memory, dict):
                _dict['memory'] = self.memory
            else:
                _dict['memory'] = self.memory.to_dict()
        if hasattr(self,
                   'os_architecture') and self.os_architecture is not None:
            _dict['os_architecture'] = self.os_architecture.to_dict()
        if hasattr(self,
                   'vcpu_architecture') and self.vcpu_architecture is not None:
            _dict['vcpu_architecture'] = self.vcpu_architecture.to_dict()
        if hasattr(self, 'vcpu_count') and self.vcpu_count is not None:
            if isinstance(self.vcpu_count, dict):
                _dict['vcpu_count'] = self.vcpu_count
            else:
                _dict['vcpu_count'] = self.vcpu_count.to_dict()
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileBandwidth():
    """
    InstanceProfileBandwidth.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfileBandwidth object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfileBandwidthFixed',
                'InstanceProfileBandwidthRange', 'InstanceProfileBandwidthEnum',
                'InstanceProfileBandwidthDependent'
            ]))
        raise Exception(msg)


class InstanceProfileCollection():
    """
    InstanceProfileCollection.

    :attr List[InstanceProfile] profiles: Collection of virtual server instance
          profiles.
    """

    def __init__(self, profiles: List['InstanceProfile']) -> None:
        """
        Initialize a InstanceProfileCollection object.

        :param List[InstanceProfile] profiles: Collection of virtual server
               instance profiles.
        """
        self.profiles = profiles

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileCollection':
        """Initialize a InstanceProfileCollection object from a json dictionary."""
        args = {}
        if 'profiles' in _dict:
            args['profiles'] = [
                InstanceProfile.from_dict(x) for x in _dict.get('profiles')
            ]
        else:
            raise ValueError(
                'Required property \'profiles\' not present in InstanceProfileCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'profiles') and self.profiles is not None:
            _dict['profiles'] = [x.to_dict() for x in self.profiles]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileIdentity():
    """
    Identifies an instance profile by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfileIdentityByName', 'InstanceProfileIdentityByHref'
            ]))
        raise Exception(msg)


class InstanceProfileMemory():
    """
    InstanceProfileMemory.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfileMemory object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfileMemoryFixed', 'InstanceProfileMemoryRange',
                'InstanceProfileMemoryEnum', 'InstanceProfileMemoryDependent'
            ]))
        raise Exception(msg)


class InstanceProfileOSArchitecture():
    """
    InstanceProfileOSArchitecture.

    :attr str type: The type for this profile field.
    :attr str default: The default OS architecture for an instance with this
          profile.
    :attr List[str] values: The supported OS architecture(s) for an instance with
          this profile.
    """

    def __init__(self, type: str, default: str, values: List[str]) -> None:
        """
        Initialize a InstanceProfileOSArchitecture object.

        :param str type: The type for this profile field.
        :param str default: The default OS architecture for an instance with this
               profile.
        :param List[str] values: The supported OS architecture(s) for an instance
               with this profile.
        """
        self.type = type
        self.default = default
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileOSArchitecture':
        """Initialize a InstanceProfileOSArchitecture object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileOSArchitecture JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileOSArchitecture JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileOSArchitecture JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileOSArchitecture object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileOSArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileOSArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileOSArchitecture') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        ENUM = 'enum'


class InstanceProfilePortSpeed():
    """
    InstanceProfilePortSpeed.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfilePortSpeed object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfilePortSpeedFixed',
                'InstanceProfilePortSpeedDependent'
            ]))
        raise Exception(msg)


class InstanceProfileReference():
    """
    InstanceProfileReference.

    :attr str name: The name for this virtual server instance profile.
    :attr str href: The URL for this virtual server instance profile.
    """

    def __init__(self, name: str, href: str) -> None:
        """
        Initialize a InstanceProfileReference object.

        :param str name: The name for this virtual server instance profile.
        :param str href: The URL for this virtual server instance profile.
        """
        self.name = name
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileReference':
        """Initialize a InstanceProfileReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceProfileReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceProfileReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileVCPU():
    """
    InstanceProfileVCPU.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfileVCPU object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfileVCPUFixed', 'InstanceProfileVCPURange',
                'InstanceProfileVCPUEnum', 'InstanceProfileVCPUDependent'
            ]))
        raise Exception(msg)


class InstanceProfileVCPUArchitecture():
    """
    InstanceProfileVCPUArchitecture.

    :attr str type: The type for this profile field.
    :attr str value: The VCPU architecture for an instance with this profile.
    :attr str default: (optional) The default VCPU architecture for an instance with
          this profile.
    """

    def __init__(self, type: str, value: str, *, default: str = None) -> None:
        """
        Initialize a InstanceProfileVCPUArchitecture object.

        :param str type: The type for this profile field.
        :param str value: The VCPU architecture for an instance with this profile.
        :param str default: (optional) The default VCPU architecture for an
               instance with this profile.
        """
        self.type = type
        self.value = value
        self.default = default

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUArchitecture':
        """Initialize a InstanceProfileVCPUArchitecture object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileVCPUArchitecture JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfileVCPUArchitecture JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUArchitecture object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        FIXED = 'fixed'


class InstancePrototype():
    """
    InstancePrototype.

    :attr str name: (optional) The unique user-defined name for this virtual server
          instance (and default system hostname). If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a InstancePrototype object.

        :param str name: (optional) The unique user-defined name for this virtual
               server instance (and default system hostname). If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstancePrototypeInstanceByImage',
                'InstancePrototypeInstanceBySourceTemplate'
            ]))
        raise Exception(msg)


class InstanceReference():
    """
    InstanceReference.

    :attr str id: The unique identifier for this virtual server instance.
    :attr str crn: The CRN for this virtual server instance.
    :attr str href: The URL for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a InstanceReference object.

        :param str id: The unique identifier for this virtual server instance.
        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReference':
        """Initialize a InstanceReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplate():
    """
    InstanceTemplate.

    :attr str id: The unique identifier for this instance template.
    :attr str href: The URL for this instance template.
    :attr str crn: The CRN for this instance template.
    :attr str name: The unique user-defined name for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 crn: str,
                 name: str,
                 created_at: datetime,
                 resource_group: 'ResourceGroupReference',
                 *,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None) -> None:
        """
        Initialize a InstanceTemplate object.

        :param str id: The unique identifier for this instance template.
        :param str href: The URL for this instance template.
        :param str crn: The CRN for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :param datetime created_at: The date and time that the instance template
               was created.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceTemplateInstanceByImage',
                'InstanceTemplateInstanceBySourceTemplate'
            ]))
        raise Exception(msg)


class InstanceTemplateCollection():
    """
    InstanceTemplateCollection.

    :attr InstanceTemplateCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceTemplateCollectionNext next: (optional) A reference to the next
          page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[InstanceTemplate] templates: Collection of instance templates.
    """

    def __init__(self,
                 first: 'InstanceTemplateCollectionFirst',
                 limit: int,
                 total_count: int,
                 templates: List['InstanceTemplate'],
                 *,
                 next: 'InstanceTemplateCollectionNext' = None) -> None:
        """
        Initialize a InstanceTemplateCollection object.

        :param InstanceTemplateCollectionFirst first: A reference to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[InstanceTemplate] templates: Collection of instance templates.
        :param InstanceTemplateCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.templates = templates

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateCollection':
        """Initialize a InstanceTemplateCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceTemplateCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceTemplateCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceTemplateCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceTemplateCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in InstanceTemplateCollection JSON'
            )
        if 'templates' in _dict:
            args['templates'] = _dict.get('templates')
        else:
            raise ValueError(
                'Required property \'templates\' not present in InstanceTemplateCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'templates') and self.templates is not None:
            templates_list = []
            for x in self.templates:
                if isinstance(x, dict):
                    templates_list.append(x)
                else:
                    templates_list.append(x.to_dict())
            _dict['templates'] = templates_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceTemplateCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateCollectionFirst':
        """Initialize a InstanceTemplateCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceTemplateCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateCollectionNext':
        """Initialize a InstanceTemplateCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentity():
    """
    Identifies an instance template by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceTemplateIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceTemplateIdentityById',
                'InstanceTemplateIdentityByHref',
                'InstanceTemplateIdentityByCRN'
            ]))
        raise Exception(msg)


class InstanceTemplatePrototype():
    """
    InstanceTemplatePrototype.

    :attr str name: (optional) The unique user-defined name for this virtual server
          instance (and default system hostname). If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a InstanceTemplatePrototype object.

        :param str name: (optional) The unique user-defined name for this virtual
               server instance (and default system hostname). If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceTemplatePrototypeInstanceByImage',
                'InstanceTemplatePrototypeInstanceBySourceTemplate'
            ]))
        raise Exception(msg)


class InstanceTemplateReference():
    """
    InstanceTemplateReference.

    :attr str id: The unique identifier for this instance template.
    :attr str href: The URL for this instance template.
    :attr str crn: The CRN for this instance template.
    """

    def __init__(self, id: str, href: str, crn: str) -> None:
        """
        Initialize a InstanceTemplateReference object.

        :param str id: The unique identifier for this instance template.
        :param str href: The URL for this instance template.
        :param str crn: The CRN for this instance template.
        """
        self.id = id
        self.href = href
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateReference':
        """Initialize a InstanceTemplateReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceTemplateReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceVCPU():
    """
    The virtual server instance VCPU configuration.

    :attr str architecture: The VCPU architecture.
    :attr int count: The number of VCPUs assigned.
    """

    def __init__(self, architecture: str, count: int) -> None:
        """
        Initialize a InstanceVCPU object.

        :param str architecture: The VCPU architecture.
        :param int count: The number of VCPUs assigned.
        """
        self.architecture = architecture
        self.count = count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceVCPU':
        """Initialize a InstanceVCPU object from a json dictionary."""
        args = {}
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError(
                'Required property \'architecture\' not present in InstanceVCPU JSON'
            )
        if 'count' in _dict:
            args['count'] = _dict.get('count')
        else:
            raise ValueError(
                'Required property \'count\' not present in InstanceVCPU JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceVCPU object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'architecture') and self.architecture is not None:
            _dict['architecture'] = self.architecture
        if hasattr(self, 'count') and self.count is not None:
            _dict['count'] = self.count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceVCPU object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceVCPU') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceVCPU') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Key():
    """
    Key.

    :attr str id: The unique identifier for this key.
    :attr str crn: The CRN for this key.
    :attr str href: The URL for this key.
    :attr str fingerprint: The fingerprint for this key.  The value is returned
          base64-encoded and prefixed with the hash algorithm (always `SHA256`).
    :attr str name: The unique user-defined name for this key. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr str public_key: The public SSH key.
    :attr str type: The cryptosystem used by this key.
    :attr ResourceGroupReference resource_group: The resource group for this key.
    :attr datetime created_at: The date and time that the key was created.
    :attr int length: The length of this key (in bits).
    """

    def __init__(self, id: str, crn: str, href: str, fingerprint: str,
                 name: str, public_key: str, type: str,
                 resource_group: 'ResourceGroupReference', created_at: datetime,
                 length: int) -> None:
        """
        Initialize a Key object.

        :param str id: The unique identifier for this key.
        :param str crn: The CRN for this key.
        :param str href: The URL for this key.
        :param str fingerprint: The fingerprint for this key.  The value is
               returned base64-encoded and prefixed with the hash algorithm (always
               `SHA256`).
        :param str name: The unique user-defined name for this key. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param str public_key: The public SSH key.
        :param str type: The cryptosystem used by this key.
        :param ResourceGroupReference resource_group: The resource group for this
               key.
        :param datetime created_at: The date and time that the key was created.
        :param int length: The length of this key (in bits).
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.fingerprint = fingerprint
        self.name = name
        self.public_key = public_key
        self.type = type
        self.resource_group = resource_group
        self.created_at = created_at
        self.length = length

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Key':
        """Initialize a Key object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in Key JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Key JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Key JSON')
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError(
                'Required property \'fingerprint\' not present in Key JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Key JSON')
        if 'public_key' in _dict:
            args['public_key'] = _dict.get('public_key')
        else:
            raise ValueError(
                'Required property \'public_key\' not present in Key JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in Key JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in Key JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in Key JSON')
        if 'length' in _dict:
            args['length'] = _dict.get('length')
        else:
            raise ValueError(
                'Required property \'length\' not present in Key JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Key object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'public_key') and self.public_key is not None:
            _dict['public_key'] = self.public_key
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'length') and self.length is not None:
            _dict['length'] = self.length
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Key object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Key') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Key') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The cryptosystem used by this key.
        """
        RSA = 'rsa'


class KeyCollection():
    """
    KeyCollection.

    :attr List[Key] keys: Collection of keys.
    """

    def __init__(self, keys: List['Key']) -> None:
        """
        Initialize a KeyCollection object.

        :param List[Key] keys: Collection of keys.
        """
        self.keys = keys

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyCollection':
        """Initialize a KeyCollection object from a json dictionary."""
        args = {}
        if 'keys' in _dict:
            args['keys'] = [Key.from_dict(x) for x in _dict.get('keys')]
        else:
            raise ValueError(
                'Required property \'keys\' not present in KeyCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'keys') and self.keys is not None:
            _dict['keys'] = [x.to_dict() for x in self.keys]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyIdentity():
    """
    Identifies a key by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a KeyIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'KeyIdentityById', 'KeyIdentityByCRN', 'KeyIdentityByHref',
                'KeyIdentityKeyIdentityByFingerprint'
            ]))
        raise Exception(msg)


class KeyReferenceInstanceInitializationContext():
    """
    KeyReferenceInstanceInitializationContext.

    """

    def __init__(self) -> None:
        """
        Initialize a KeyReferenceInstanceInitializationContext object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'KeyReferenceInstanceInitializationContextKeyReference',
                'KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint'
            ]))
        raise Exception(msg)


class LoadBalancer():
    """
    LoadBalancer.

    :attr LoadBalancerProfileReference profile: The profile to use for this load
          balancer.
    :attr str id: The unique identifier for this load balancer.
    :attr str crn: The load balancer's CRN.
    :attr str href: The load balancer's canonical URL.
    :attr str name: The unique user-defined name for this load balancer.
    :attr datetime created_at: The date and time that this load balancer was
          created.
    :attr str hostname: Fully qualified domain name assigned to this load balancer.
    :attr bool is_public: The type of this load balancer, public or private.
    :attr List[LoadBalancerListenerReference] listeners: The listeners of this load
          balancer.
    :attr str operating_status: The operating status of this load balancer.
    :attr List[LoadBalancerPoolReference] pools: The pools of this load balancer.
    :attr List[IP] private_ips: The private IP addresses assigned to this load
          balancer.
    :attr str provisioning_status: The provisioning status of this load balancer.
    :attr List[IP] public_ips: The public IP addresses assigned to this load
          balancer. These are applicable only for public load balancers.
    :attr ResourceGroupReference resource_group: The resource group for this load
          balancer.
    :attr List[SubnetReference] subnets: The subnets this load balancer is part of.
    """

    def __init__(self, profile: 'LoadBalancerProfileReference', id: str,
                 crn: str, href: str, name: str, created_at: datetime,
                 hostname: str, is_public: bool,
                 listeners: List['LoadBalancerListenerReference'],
                 operating_status: str,
                 pools: List['LoadBalancerPoolReference'],
                 private_ips: List['IP'], provisioning_status: str,
                 public_ips: List['IP'],
                 resource_group: 'ResourceGroupReference',
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a LoadBalancer object.

        :param LoadBalancerProfileReference profile: The profile to use for this
               load balancer.
        :param str id: The unique identifier for this load balancer.
        :param str crn: The load balancer's CRN.
        :param str href: The load balancer's canonical URL.
        :param str name: The unique user-defined name for this load balancer.
        :param datetime created_at: The date and time that this load balancer was
               created.
        :param str hostname: Fully qualified domain name assigned to this load
               balancer.
        :param bool is_public: The type of this load balancer, public or private.
        :param List[LoadBalancerListenerReference] listeners: The listeners of this
               load balancer.
        :param str operating_status: The operating status of this load balancer.
        :param List[LoadBalancerPoolReference] pools: The pools of this load
               balancer.
        :param List[IP] private_ips: The private IP addresses assigned to this load
               balancer.
        :param str provisioning_status: The provisioning status of this load
               balancer.
        :param List[IP] public_ips: The public IP addresses assigned to this load
               balancer. These are applicable only for public load balancers.
        :param ResourceGroupReference resource_group: The resource group for this
               load balancer.
        :param List[SubnetReference] subnets: The subnets this load balancer is
               part of.
        """
        self.profile = profile
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.created_at = created_at
        self.hostname = hostname
        self.is_public = is_public
        self.listeners = listeners
        self.operating_status = operating_status
        self.pools = pools
        self.private_ips = private_ips
        self.provisioning_status = provisioning_status
        self.public_ips = public_ips
        self.resource_group = resource_group
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancer':
        """Initialize a LoadBalancer object from a json dictionary."""
        args = {}
        if 'profile' in _dict:
            args['profile'] = LoadBalancerProfileReference.from_dict(
                _dict.get('profile'))
        else:
            raise ValueError(
                'Required property \'profile\' not present in LoadBalancer JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancer JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in LoadBalancer JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancer JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancer JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in LoadBalancer JSON'
            )
        if 'hostname' in _dict:
            args['hostname'] = _dict.get('hostname')
        else:
            raise ValueError(
                'Required property \'hostname\' not present in LoadBalancer JSON'
            )
        if 'is_public' in _dict:
            args['is_public'] = _dict.get('is_public')
        else:
            raise ValueError(
                'Required property \'is_public\' not present in LoadBalancer JSON'
            )
        if 'listeners' in _dict:
            args['listeners'] = [
                LoadBalancerListenerReference.from_dict(x)
                for x in _dict.get('listeners')
            ]
        else:
            raise ValueError(
                'Required property \'listeners\' not present in LoadBalancer JSON'
            )
        if 'operating_status' in _dict:
            args['operating_status'] = _dict.get('operating_status')
        else:
            raise ValueError(
                'Required property \'operating_status\' not present in LoadBalancer JSON'
            )
        if 'pools' in _dict:
            args['pools'] = [
                LoadBalancerPoolReference.from_dict(x)
                for x in _dict.get('pools')
            ]
        else:
            raise ValueError(
                'Required property \'pools\' not present in LoadBalancer JSON')
        if 'private_ips' in _dict:
            args['private_ips'] = [
                IP.from_dict(x) for x in _dict.get('private_ips')
            ]
        else:
            raise ValueError(
                'Required property \'private_ips\' not present in LoadBalancer JSON'
            )
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancer JSON'
            )
        if 'public_ips' in _dict:
            args['public_ips'] = [
                IP.from_dict(x) for x in _dict.get('public_ips')
            ]
        else:
            raise ValueError(
                'Required property \'public_ips\' not present in LoadBalancer JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in LoadBalancer JSON'
            )
        if 'subnets' in _dict:
            args['subnets'] = [
                SubnetReference.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in LoadBalancer JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancer object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'profile') and self.profile is not None:
            _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'hostname') and self.hostname is not None:
            _dict['hostname'] = self.hostname
        if hasattr(self, 'is_public') and self.is_public is not None:
            _dict['is_public'] = self.is_public
        if hasattr(self, 'listeners') and self.listeners is not None:
            _dict['listeners'] = [x.to_dict() for x in self.listeners]
        if hasattr(self,
                   'operating_status') and self.operating_status is not None:
            _dict['operating_status'] = self.operating_status
        if hasattr(self, 'pools') and self.pools is not None:
            _dict['pools'] = [x.to_dict() for x in self.pools]
        if hasattr(self, 'private_ips') and self.private_ips is not None:
            _dict['private_ips'] = [x.to_dict() for x in self.private_ips]
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        if hasattr(self, 'public_ips') and self.public_ips is not None:
            _dict['public_ips'] = [x.to_dict() for x in self.public_ips]
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'subnets') and self.subnets is not None:
            _dict['subnets'] = [x.to_dict() for x in self.subnets]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancer') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class OperatingStatusEnum(str, Enum):
        """
        The operating status of this load balancer.
        """
        OFFLINE = 'offline'
        ONLINE = 'online'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this load balancer.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerCollection():
    """
    LoadBalancerCollection.

    :attr List[LoadBalancer] load_balancers: Collection of load balancers.
    """

    def __init__(self, load_balancers: List['LoadBalancer']) -> None:
        """
        Initialize a LoadBalancerCollection object.

        :param List[LoadBalancer] load_balancers: Collection of load balancers.
        """
        self.load_balancers = load_balancers

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerCollection':
        """Initialize a LoadBalancerCollection object from a json dictionary."""
        args = {}
        if 'load_balancers' in _dict:
            args['load_balancers'] = [
                LoadBalancer.from_dict(x) for x in _dict.get('load_balancers')
            ]
        else:
            raise ValueError(
                'Required property \'load_balancers\' not present in LoadBalancerCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'load_balancers') and self.load_balancers is not None:
            _dict['load_balancers'] = [x.to_dict() for x in self.load_balancers]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentity():
    """
    Identifies a load balancer by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerIdentityById', 'LoadBalancerIdentityByCRN',
                'LoadBalancerIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerListener():
    """
    LoadBalancerListener.

    :attr str id: The unique identifier for this load balancer listener.
    :attr str href: The listener's canonical URL.
    :attr int connection_limit: (optional) The connection limit of the listener.
    :attr int port: The listener port number.
    :attr str protocol: The listener protocol. Load balancers in the `network`
          family support `tcp`. Load balancers in the `application` family support `tcp`,
          `http`, and `https`.
    :attr CertificateInstanceReference certificate_instance: (optional) The
          certificate instance used for SSL termination. It is applicable only to `https`
          protocol.
    :attr datetime created_at: The date and time that this listener was created.
    :attr LoadBalancerPoolReference default_pool: (optional) The default pool
          associated with the listener.
    :attr List[LoadBalancerListenerPolicyReference] policies: (optional) The list of
          policies of this listener.
    :attr str provisioning_status: The provisioning status of this listener.
    """

    def __init__(
            self,
            id: str,
            href: str,
            port: int,
            protocol: str,
            created_at: datetime,
            provisioning_status: str,
            *,
            connection_limit: int = None,
            certificate_instance: 'CertificateInstanceReference' = None,
            default_pool: 'LoadBalancerPoolReference' = None,
            policies: List['LoadBalancerListenerPolicyReference'] = None
    ) -> None:
        """
        Initialize a LoadBalancerListener object.

        :param str id: The unique identifier for this load balancer listener.
        :param str href: The listener's canonical URL.
        :param int port: The listener port number.
        :param str protocol: The listener protocol. Load balancers in the `network`
               family support `tcp`. Load balancers in the `application` family support
               `tcp`, `http`, and `https`.
        :param datetime created_at: The date and time that this listener was
               created.
        :param str provisioning_status: The provisioning status of this listener.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param CertificateInstanceReference certificate_instance: (optional) The
               certificate instance used for SSL termination. It is applicable only to
               `https`
               protocol.
        :param LoadBalancerPoolReference default_pool: (optional) The default pool
               associated with the listener.
        :param List[LoadBalancerListenerPolicyReference] policies: (optional) The
               list of policies of this listener.
        """
        self.id = id
        self.href = href
        self.connection_limit = connection_limit
        self.port = port
        self.protocol = protocol
        self.certificate_instance = certificate_instance
        self.created_at = created_at
        self.default_pool = default_pool
        self.policies = policies
        self.provisioning_status = provisioning_status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListener':
        """Initialize a LoadBalancerListener object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListener JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListener JSON'
            )
        if 'connection_limit' in _dict:
            args['connection_limit'] = _dict.get('connection_limit')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        else:
            raise ValueError(
                'Required property \'port\' not present in LoadBalancerListener JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in LoadBalancerListener JSON'
            )
        if 'certificate_instance' in _dict:
            args[
                'certificate_instance'] = CertificateInstanceReference.from_dict(
                    _dict.get('certificate_instance'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in LoadBalancerListener JSON'
            )
        if 'default_pool' in _dict:
            args['default_pool'] = LoadBalancerPoolReference.from_dict(
                _dict.get('default_pool'))
        if 'policies' in _dict:
            args['policies'] = [
                LoadBalancerListenerPolicyReference.from_dict(x)
                for x in _dict.get('policies')
            ]
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancerListener JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListener object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self,
                   'connection_limit') and self.connection_limit is not None:
            _dict['connection_limit'] = self.connection_limit
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'certificate_instance'
                  ) and self.certificate_instance is not None:
            _dict['certificate_instance'] = self.certificate_instance.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'default_pool') and self.default_pool is not None:
            _dict['default_pool'] = self.default_pool.to_dict()
        if hasattr(self, 'policies') and self.policies is not None:
            _dict['policies'] = [x.to_dict() for x in self.policies]
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListener object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListener') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListener') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolEnum(str, Enum):
        """
        The listener protocol. Load balancers in the `network` family support `tcp`. Load
        balancers in the `application` family support `tcp`, `http`, and `https`.
        """
        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this listener.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerListenerCollection():
    """
    LoadBalancerListenerCollection.

    :attr List[LoadBalancerListener] listeners: Collection of listeners.
    """

    def __init__(self, listeners: List['LoadBalancerListener']) -> None:
        """
        Initialize a LoadBalancerListenerCollection object.

        :param List[LoadBalancerListener] listeners: Collection of listeners.
        """
        self.listeners = listeners

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerCollection':
        """Initialize a LoadBalancerListenerCollection object from a json dictionary."""
        args = {}
        if 'listeners' in _dict:
            args['listeners'] = [
                LoadBalancerListener.from_dict(x)
                for x in _dict.get('listeners')
            ]
        else:
            raise ValueError(
                'Required property \'listeners\' not present in LoadBalancerListenerCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'listeners') and self.listeners is not None:
            _dict['listeners'] = [x.to_dict() for x in self.listeners]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicy():
    """
    LoadBalancerListenerPolicy.

    :attr str id: The policy's unique identifier.
    :attr str href: The listener policy's canonical URL.
    :attr str name: The user-defined name for this policy.
    :attr int priority: Priority of the policy. Lower value indicates higher
          priority.
    :attr str action: The policy action.
    :attr datetime created_at: The date and time that this policy was created.
    :attr str provisioning_status: The provisioning status of this policy.
    :attr List[LoadBalancerListenerPolicyRuleReference] rules: The rules of this
          policy.
    :attr LoadBalancerListenerPolicyTargetReference target: (optional)
          `LoadBalancerPoolReference` is in the response if `action` is `forward`.
          `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is
          `redirect`.
    """

    def __init__(
            self,
            id: str,
            href: str,
            name: str,
            priority: int,
            action: str,
            created_at: datetime,
            provisioning_status: str,
            rules: List['LoadBalancerListenerPolicyRuleReference'],
            *,
            target: 'LoadBalancerListenerPolicyTargetReference' = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicy object.

        :param str id: The policy's unique identifier.
        :param str href: The listener policy's canonical URL.
        :param str name: The user-defined name for this policy.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str action: The policy action.
        :param datetime created_at: The date and time that this policy was created.
        :param str provisioning_status: The provisioning status of this policy.
        :param List[LoadBalancerListenerPolicyRuleReference] rules: The rules of
               this policy.
        :param LoadBalancerListenerPolicyTargetReference target: (optional)
               `LoadBalancerPoolReference` is in the response if `action` is `forward`.
               `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is
               `redirect`.
        """
        self.id = id
        self.href = href
        self.name = name
        self.priority = priority
        self.action = action
        self.created_at = created_at
        self.provisioning_status = provisioning_status
        self.rules = rules
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicy':
        """Initialize a LoadBalancerListenerPolicy object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        else:
            raise ValueError(
                'Required property \'priority\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                LoadBalancerListenerPolicyRuleReference.from_dict(x)
                for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The policy action.
        """
        FORWARD = 'forward'
        REDIRECT = 'redirect'
        REJECT = 'reject'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this policy.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerListenerPolicyCollection():
    """
    LoadBalancerListenerPolicyCollection.

    :attr List[LoadBalancerListenerPolicy] policies: Collection of policies.
    """

    def __init__(self, policies: List['LoadBalancerListenerPolicy']) -> None:
        """
        Initialize a LoadBalancerListenerPolicyCollection object.

        :param List[LoadBalancerListenerPolicy] policies: Collection of policies.
        """
        self.policies = policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyCollection':
        """Initialize a LoadBalancerListenerPolicyCollection object from a json dictionary."""
        args = {}
        if 'policies' in _dict:
            args['policies'] = [
                LoadBalancerListenerPolicy.from_dict(x)
                for x in _dict.get('policies')
            ]
        else:
            raise ValueError(
                'Required property \'policies\' not present in LoadBalancerListenerPolicyCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'policies') and self.policies is not None:
            _dict['policies'] = [x.to_dict() for x in self.policies]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPatchTarget():
    """
    When `action` is `forward`, `LoadBalancerPoolIdentity` specifies which pool the load
    balancer forwards the traffic to. When `action` is `redirect`,
    `LoadBalancerListenerPolicyRedirectURLPatch` specifies the url and http status code
    used in the redirect response.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatchTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentity',
                'LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyPrototype():
    """
    LoadBalancerListenerPolicyPrototype.

    :attr str name: (optional) The user-defined name for this policy. Names must be
          unique within the load balancer listener the policy resides in.
    :attr int priority: Priority of the policy. Lower value indicates higher
          priority.
    :attr str action: The policy action.
    :attr List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The list
          of rules of this policy.
    :attr LoadBalancerListenerPolicyPrototypeTarget target: (optional) When `action`
          is `forward`, `LoadBalancerPoolIdentity` is required to specify which
          pool the load balancer forwards the traffic to. When `action` is `redirect`,
          `LoadBalancerListenerPolicyRedirectURLPrototype` is required to specify the url
          and
          http status code used in the redirect response.
    """

    def __init__(
            self,
            priority: int,
            action: str,
            *,
            name: str = None,
            rules: List['LoadBalancerListenerPolicyRulePrototype'] = None,
            target: 'LoadBalancerListenerPolicyPrototypeTarget' = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototype object.

        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str action: The policy action.
        :param str name: (optional) The user-defined name for this policy. Names
               must be unique within the load balancer listener the policy resides in.
        :param List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The
               list of rules of this policy.
        :param LoadBalancerListenerPolicyPrototypeTarget target: (optional) When
               `action` is `forward`, `LoadBalancerPoolIdentity` is required to specify
               which
               pool the load balancer forwards the traffic to. When `action` is
               `redirect`,
               `LoadBalancerListenerPolicyRedirectURLPrototype` is required to specify the
               url and
               http status code used in the redirect response.
        """
        self.name = name
        self.priority = priority
        self.action = action
        self.rules = rules
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyPrototype':
        """Initialize a LoadBalancerListenerPolicyPrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        else:
            raise ValueError(
                'Required property \'priority\' not present in LoadBalancerListenerPolicyPrototype JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in LoadBalancerListenerPolicyPrototype JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                LoadBalancerListenerPolicyRulePrototype.from_dict(x)
                for x in _dict.get('rules')
            ]
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The policy action.
        """
        FORWARD = 'forward'
        REDIRECT = 'redirect'
        REJECT = 'reject'


class LoadBalancerListenerPolicyPrototypeTarget():
    """
    When `action` is `forward`, `LoadBalancerPoolIdentity` is required to specify which
    pool the load balancer forwards the traffic to. When `action` is `redirect`,
    `LoadBalancerListenerPolicyRedirectURLPrototype` is required to specify the url and
    http status code used in the redirect response.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototypeTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentity',
                'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyReference():
    """
    LoadBalancerListenerPolicyReference.

    :attr str id: The policy's unique identifier.
    :attr str href: The listener policy's canonical URL.
    """

    def __init__(self, id: str, href: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyReference object.

        :param str id: The policy's unique identifier.
        :param str href: The listener policy's canonical URL.
        """
        self.id = id
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyReference':
        """Initialize a LoadBalancerListenerPolicyReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyRule():
    """
    LoadBalancerListenerPolicyRule.

    :attr str id: The rule's unique identifier.
    :attr str href: The rule's canonical URL.
    :attr str condition: The condition of the rule.
    :attr str field: (optional) HTTP header field. This is only applicable to
          "header" rule type.
    :attr str type: The type of the rule.
    :attr str value: Value to be matched for rule condition.
    :attr datetime created_at: The date and time that this rule was created.
    :attr str provisioning_status: The provisioning status of this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 condition: str,
                 type: str,
                 value: str,
                 created_at: datetime,
                 provisioning_status: str,
                 *,
                 field: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRule object.

        :param str id: The rule's unique identifier.
        :param str href: The rule's canonical URL.
        :param str condition: The condition of the rule.
        :param str type: The type of the rule.
        :param str value: Value to be matched for rule condition.
        :param datetime created_at: The date and time that this rule was created.
        :param str provisioning_status: The provisioning status of this rule.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        """
        self.id = id
        self.href = href
        self.condition = condition
        self.field = field
        self.type = type
        self.value = value
        self.created_at = created_at
        self.provisioning_status = provisioning_status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRule':
        """Initialize a LoadBalancerListenerPolicyRule object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        else:
            raise ValueError(
                'Required property \'condition\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRule object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'condition') and self.condition is not None:
            _dict['condition'] = self.condition
        if hasattr(self, 'field') and self.field is not None:
            _dict['field'] = self.field
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRule object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRule') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRule') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConditionEnum(str, Enum):
        """
        The condition of the rule.
        """
        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'

    class TypeEnum(str, Enum):
        """
        The type of the rule.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this rule.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerListenerPolicyRuleCollection():
    """
    LoadBalancerListenerPolicyRuleCollection.

    :attr List[LoadBalancerListenerPolicyRule] rules: Collection of rules.
    """

    def __init__(self, rules: List['LoadBalancerListenerPolicyRule']) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleCollection object.

        :param List[LoadBalancerListenerPolicyRule] rules: Collection of rules.
        """
        self.rules = rules

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerListenerPolicyRuleCollection':
        """Initialize a LoadBalancerListenerPolicyRuleCollection object from a json dictionary."""
        args = {}
        if 'rules' in _dict:
            args['rules'] = [
                LoadBalancerListenerPolicyRule.from_dict(x)
                for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in LoadBalancerListenerPolicyRuleCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRuleCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRuleCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRuleCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRuleCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyRulePrototype():
    """
    LoadBalancerListenerPolicyRulePrototype.

    :attr str condition: The condition of the rule.
    :attr str field: (optional) HTTP header field. This is only applicable to
          "header" rule type.
    :attr str type: The type of the rule.
    :attr str value: Value to be matched for rule condition.
    """

    def __init__(self,
                 condition: str,
                 type: str,
                 value: str,
                 *,
                 field: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePrototype object.

        :param str condition: The condition of the rule.
        :param str type: The type of the rule.
        :param str value: Value to be matched for rule condition.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        """
        self.condition = condition
        self.field = field
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerListenerPolicyRulePrototype':
        """Initialize a LoadBalancerListenerPolicyRulePrototype object from a json dictionary."""
        args = {}
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        else:
            raise ValueError(
                'Required property \'condition\' not present in LoadBalancerListenerPolicyRulePrototype JSON'
            )
        if 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerListenerPolicyRulePrototype JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in LoadBalancerListenerPolicyRulePrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRulePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'condition') and self.condition is not None:
            _dict['condition'] = self.condition
        if hasattr(self, 'field') and self.field is not None:
            _dict['field'] = self.field
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRulePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRulePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRulePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConditionEnum(str, Enum):
        """
        The condition of the rule.
        """
        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'

    class TypeEnum(str, Enum):
        """
        The type of the rule.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'


class LoadBalancerListenerPolicyRuleReference():
    """
    LoadBalancerListenerPolicyRuleReference.

    :attr str id: The rule's unique identifier.
    :attr str href: The rule's canonical URL.
    """

    def __init__(self, id: str, href: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleReference object.

        :param str id: The rule's unique identifier.
        :param str href: The rule's canonical URL.
        """
        self.id = id
        self.href = href

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerListenerPolicyRuleReference':
        """Initialize a LoadBalancerListenerPolicyRuleReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyRuleReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyRuleReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRuleReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRuleReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRuleReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRuleReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetReference():
    """
    `LoadBalancerPoolReference` is in the response if `action` is `forward`.
    `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is `redirect`.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetReference object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference',
                'LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPrototypeLoadBalancerContext():
    """
    LoadBalancerListenerPrototypeLoadBalancerContext.

    :attr int connection_limit: (optional) The connection limit of the listener.
    :attr int port: The listener port number.
    :attr str protocol: The listener protocol. Load balancers in the `network`
          family support `tcp`. Load balancers in the `application` family support `tcp`,
          `http`, and `https`.
    :attr LoadBalancerPoolIdentityByName default_pool: (optional) The default pool
          associated with the listener.
    """

    def __init__(self,
                 port: int,
                 protocol: str,
                 *,
                 connection_limit: int = None,
                 default_pool: 'LoadBalancerPoolIdentityByName' = None) -> None:
        """
        Initialize a LoadBalancerListenerPrototypeLoadBalancerContext object.

        :param int port: The listener port number.
        :param str protocol: The listener protocol. Load balancers in the `network`
               family support `tcp`. Load balancers in the `application` family support
               `tcp`, `http`, and `https`.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentityByName default_pool: (optional) The default
               pool associated with the listener.
        """
        self.connection_limit = connection_limit
        self.port = port
        self.protocol = protocol
        self.default_pool = default_pool

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'LoadBalancerListenerPrototypeLoadBalancerContext':
        """Initialize a LoadBalancerListenerPrototypeLoadBalancerContext object from a json dictionary."""
        args = {}
        if 'connection_limit' in _dict:
            args['connection_limit'] = _dict.get('connection_limit')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        else:
            raise ValueError(
                'Required property \'port\' not present in LoadBalancerListenerPrototypeLoadBalancerContext JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in LoadBalancerListenerPrototypeLoadBalancerContext JSON'
            )
        if 'default_pool' in _dict:
            args['default_pool'] = LoadBalancerPoolIdentityByName.from_dict(
                _dict.get('default_pool'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPrototypeLoadBalancerContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'connection_limit') and self.connection_limit is not None:
            _dict['connection_limit'] = self.connection_limit
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'default_pool') and self.default_pool is not None:
            _dict['default_pool'] = self.default_pool.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPrototypeLoadBalancerContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'LoadBalancerListenerPrototypeLoadBalancerContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'LoadBalancerListenerPrototypeLoadBalancerContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolEnum(str, Enum):
        """
        The listener protocol. Load balancers in the `network` family support `tcp`. Load
        balancers in the `application` family support `tcp`, `http`, and `https`.
        """
        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'


class LoadBalancerListenerReference():
    """
    LoadBalancerListenerReference.

    :attr str id: The unique identifier for this load balancer listener.
    :attr str href: The listener's canonical URL.
    """

    def __init__(self, id: str, href: str) -> None:
        """
        Initialize a LoadBalancerListenerReference object.

        :param str id: The unique identifier for this load balancer listener.
        :param str href: The listener's canonical URL.
        """
        self.id = id
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerReference':
        """Initialize a LoadBalancerListenerReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPool():
    """
    LoadBalancerPool.

    :attr str id: The unique identifier for this load balancer pool.
    :attr str href: The pool's canonical URL.
    :attr str name: The user-defined name for this load balancer pool.
    :attr str algorithm: The load balancing algorithm.
    :attr str protocol: The protocol used for this load balancer pool.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the pool on which the unexpected
          property value was encountered.
    :attr datetime created_at: The date and time that this pool was created.
    :attr LoadBalancerPoolHealthMonitor health_monitor: The health monitor of this
          pool.
    :attr InstanceGroupReference instance_group: (optional) The instance group that
          is managing this pool.
    :attr List[LoadBalancerPoolMemberReference] members: (optional) The backend
          server members of the pool.
    :attr str provisioning_status: The provisioning status of this pool.
    :attr LoadBalancerPoolSessionPersistence session_persistence: (optional) The
          session persistence of this pool.
    """

    def __init__(
        self,
        id: str,
        href: str,
        name: str,
        algorithm: str,
        protocol: str,
        created_at: datetime,
        health_monitor: 'LoadBalancerPoolHealthMonitor',
        provisioning_status: str,
        *,
        instance_group: 'InstanceGroupReference' = None,
        members: List['LoadBalancerPoolMemberReference'] = None,
        session_persistence: 'LoadBalancerPoolSessionPersistence' = None
    ) -> None:
        """
        Initialize a LoadBalancerPool object.

        :param str id: The unique identifier for this load balancer pool.
        :param str href: The pool's canonical URL.
        :param str name: The user-defined name for this load balancer pool.
        :param str algorithm: The load balancing algorithm.
        :param str protocol: The protocol used for this load balancer pool.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the pool on
               which the unexpected property value was encountered.
        :param datetime created_at: The date and time that this pool was created.
        :param LoadBalancerPoolHealthMonitor health_monitor: The health monitor of
               this pool.
        :param str provisioning_status: The provisioning status of this pool.
        :param InstanceGroupReference instance_group: (optional) The instance group
               that is managing this pool.
        :param List[LoadBalancerPoolMemberReference] members: (optional) The
               backend server members of the pool.
        :param LoadBalancerPoolSessionPersistence session_persistence: (optional)
               The session persistence of this pool.
        """
        self.id = id
        self.href = href
        self.name = name
        self.algorithm = algorithm
        self.protocol = protocol
        self.created_at = created_at
        self.health_monitor = health_monitor
        self.instance_group = instance_group
        self.members = members
        self.provisioning_status = provisioning_status
        self.session_persistence = session_persistence

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPool':
        """Initialize a LoadBalancerPool object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPool JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPool JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerPool JSON'
            )
        if 'algorithm' in _dict:
            args['algorithm'] = _dict.get('algorithm')
        else:
            raise ValueError(
                'Required property \'algorithm\' not present in LoadBalancerPool JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in LoadBalancerPool JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in LoadBalancerPool JSON'
            )
        if 'health_monitor' in _dict:
            args['health_monitor'] = LoadBalancerPoolHealthMonitor.from_dict(
                _dict.get('health_monitor'))
        else:
            raise ValueError(
                'Required property \'health_monitor\' not present in LoadBalancerPool JSON'
            )
        if 'instance_group' in _dict:
            args['instance_group'] = InstanceGroupReference.from_dict(
                _dict.get('instance_group'))
        if 'members' in _dict:
            args['members'] = [
                LoadBalancerPoolMemberReference.from_dict(x)
                for x in _dict.get('members')
            ]
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancerPool JSON'
            )
        if 'session_persistence' in _dict:
            args[
                'session_persistence'] = LoadBalancerPoolSessionPersistence.from_dict(
                    _dict.get('session_persistence'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPool object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'algorithm') and self.algorithm is not None:
            _dict['algorithm'] = self.algorithm
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'health_monitor') and self.health_monitor is not None:
            _dict['health_monitor'] = self.health_monitor.to_dict()
        if hasattr(self, 'instance_group') and self.instance_group is not None:
            _dict['instance_group'] = self.instance_group.to_dict()
        if hasattr(self, 'members') and self.members is not None:
            _dict['members'] = [x.to_dict() for x in self.members]
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        if hasattr(
                self,
                'session_persistence') and self.session_persistence is not None:
            _dict['session_persistence'] = self.session_persistence.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPool object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPool') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPool') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AlgorithmEnum(str, Enum):
        """
        The load balancing algorithm.
        """
        LEAST_CONNECTIONS = 'least_connections'
        ROUND_ROBIN = 'round_robin'
        WEIGHTED_ROUND_ROBIN = 'weighted_round_robin'

    class ProtocolEnum(str, Enum):
        """
        The protocol used for this load balancer pool.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the pool on which the unexpected
        property value was encountered.
        """
        HTTP = 'http'
        TCP = 'tcp'
        HTTPS = 'https'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this pool.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerPoolCollection():
    """
    LoadBalancerPoolCollection.

    :attr List[LoadBalancerPool] pools: Collection of pools.
    """

    def __init__(self, pools: List['LoadBalancerPool']) -> None:
        """
        Initialize a LoadBalancerPoolCollection object.

        :param List[LoadBalancerPool] pools: Collection of pools.
        """
        self.pools = pools

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolCollection':
        """Initialize a LoadBalancerPoolCollection object from a json dictionary."""
        args = {}
        if 'pools' in _dict:
            args['pools'] = [
                LoadBalancerPool.from_dict(x) for x in _dict.get('pools')
            ]
        else:
            raise ValueError(
                'Required property \'pools\' not present in LoadBalancerPoolCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'pools') and self.pools is not None:
            _dict['pools'] = [x.to_dict() for x in self.pools]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolHealthMonitor():
    """
    LoadBalancerPoolHealthMonitor.

    :attr int delay: The health check interval in seconds. Interval must be greater
          than timeout value.
    :attr int max_retries: The health check max retries.
    :attr int port: (optional) The health check port number. If specified, this
          overrides the ports specified in the server member resources.
    :attr int timeout: The health check timeout in seconds.
    :attr str type: The protocol type of this load balancer pool health monitor.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the health monitor on which the
          unexpected property value was encountered.
    :attr str url_path: (optional) The health check URL. This is applicable only to
          `http` type of health monitor.
    """

    def __init__(self,
                 delay: int,
                 max_retries: int,
                 timeout: int,
                 type: str,
                 *,
                 port: int = None,
                 url_path: str = None) -> None:
        """
        Initialize a LoadBalancerPoolHealthMonitor object.

        :param int delay: The health check interval in seconds. Interval must be
               greater than timeout value.
        :param int max_retries: The health check max retries.
        :param int timeout: The health check timeout in seconds.
        :param str type: The protocol type of this load balancer pool health
               monitor.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the health
               monitor on which the unexpected property value was encountered.
        :param int port: (optional) The health check port number. If specified,
               this overrides the ports specified in the server member resources.
        :param str url_path: (optional) The health check URL. This is applicable
               only to `http` type of health monitor.
        """
        self.delay = delay
        self.max_retries = max_retries
        self.port = port
        self.timeout = timeout
        self.type = type
        self.url_path = url_path

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolHealthMonitor':
        """Initialize a LoadBalancerPoolHealthMonitor object from a json dictionary."""
        args = {}
        if 'delay' in _dict:
            args['delay'] = _dict.get('delay')
        else:
            raise ValueError(
                'Required property \'delay\' not present in LoadBalancerPoolHealthMonitor JSON'
            )
        if 'max_retries' in _dict:
            args['max_retries'] = _dict.get('max_retries')
        else:
            raise ValueError(
                'Required property \'max_retries\' not present in LoadBalancerPoolHealthMonitor JSON'
            )
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        if 'timeout' in _dict:
            args['timeout'] = _dict.get('timeout')
        else:
            raise ValueError(
                'Required property \'timeout\' not present in LoadBalancerPoolHealthMonitor JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerPoolHealthMonitor JSON'
            )
        if 'url_path' in _dict:
            args['url_path'] = _dict.get('url_path')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolHealthMonitor object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'delay') and self.delay is not None:
            _dict['delay'] = self.delay
        if hasattr(self, 'max_retries') and self.max_retries is not None:
            _dict['max_retries'] = self.max_retries
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'timeout') and self.timeout is not None:
            _dict['timeout'] = self.timeout
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'url_path') and self.url_path is not None:
            _dict['url_path'] = self.url_path
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolHealthMonitor object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolHealthMonitor') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolHealthMonitor') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The protocol type of this load balancer pool health monitor.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the health monitor on which the
        unexpected property value was encountered.
        """
        HTTP = 'http'
        TCP = 'tcp'
        HTTPS = 'https'


class LoadBalancerPoolHealthMonitorPatch():
    """
    LoadBalancerPoolHealthMonitorPatch.

    :attr int delay: The health check interval in seconds. Interval must be greater
          than timeout value.
    :attr int max_retries: The health check max retries.
    :attr int port: (optional) The health check port number. If specified, this
          overrides the ports specified in the server member resources. Specify `null` to
          remove an existing port value.
    :attr int timeout: The health check timeout in seconds.
    :attr str type: The protocol type of this load balancer pool health monitor.
    :attr str url_path: (optional) The health check URL. This is applicable only to
          `http` type of health monitor.
    """

    def __init__(self,
                 delay: int,
                 max_retries: int,
                 timeout: int,
                 type: str,
                 *,
                 port: int = None,
                 url_path: str = None) -> None:
        """
        Initialize a LoadBalancerPoolHealthMonitorPatch object.

        :param int delay: The health check interval in seconds. Interval must be
               greater than timeout value.
        :param int max_retries: The health check max retries.
        :param int timeout: The health check timeout in seconds.
        :param str type: The protocol type of this load balancer pool health
               monitor.
        :param int port: (optional) The health check port number. If specified,
               this overrides the ports specified in the server member resources. Specify
               `null` to remove an existing port value.
        :param str url_path: (optional) The health check URL. This is applicable
               only to `http` type of health monitor.
        """
        self.delay = delay
        self.max_retries = max_retries
        self.port = port
        self.timeout = timeout
        self.type = type
        self.url_path = url_path

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolHealthMonitorPatch':
        """Initialize a LoadBalancerPoolHealthMonitorPatch object from a json dictionary."""
        args = {}
        if 'delay' in _dict:
            args['delay'] = _dict.get('delay')
        else:
            raise ValueError(
                'Required property \'delay\' not present in LoadBalancerPoolHealthMonitorPatch JSON'
            )
        if 'max_retries' in _dict:
            args['max_retries'] = _dict.get('max_retries')
        else:
            raise ValueError(
                'Required property \'max_retries\' not present in LoadBalancerPoolHealthMonitorPatch JSON'
            )
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        if 'timeout' in _dict:
            args['timeout'] = _dict.get('timeout')
        else:
            raise ValueError(
                'Required property \'timeout\' not present in LoadBalancerPoolHealthMonitorPatch JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerPoolHealthMonitorPatch JSON'
            )
        if 'url_path' in _dict:
            args['url_path'] = _dict.get('url_path')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolHealthMonitorPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'delay') and self.delay is not None:
            _dict['delay'] = self.delay
        if hasattr(self, 'max_retries') and self.max_retries is not None:
            _dict['max_retries'] = self.max_retries
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'timeout') and self.timeout is not None:
            _dict['timeout'] = self.timeout
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'url_path') and self.url_path is not None:
            _dict['url_path'] = self.url_path
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolHealthMonitorPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolHealthMonitorPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolHealthMonitorPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The protocol type of this load balancer pool health monitor.
        """
        HTTP = 'http'
        TCP = 'tcp'
        HTTPS = 'https'


class LoadBalancerPoolHealthMonitorPrototype():
    """
    LoadBalancerPoolHealthMonitorPrototype.

    :attr int delay: The health check interval in seconds. Interval must be greater
          than timeout value.
    :attr int max_retries: The health check max retries.
    :attr int port: (optional) The health check port number. If specified, this
          overrides the ports specified in the server member resources.
    :attr int timeout: The health check timeout in seconds.
    :attr str type: The protocol type of this load balancer pool health monitor.
    :attr str url_path: (optional) The health check URL. This is applicable only to
          `http` type of health monitor.
    """

    def __init__(self,
                 delay: int,
                 max_retries: int,
                 timeout: int,
                 type: str,
                 *,
                 port: int = None,
                 url_path: str = None) -> None:
        """
        Initialize a LoadBalancerPoolHealthMonitorPrototype object.

        :param int delay: The health check interval in seconds. Interval must be
               greater than timeout value.
        :param int max_retries: The health check max retries.
        :param int timeout: The health check timeout in seconds.
        :param str type: The protocol type of this load balancer pool health
               monitor.
        :param int port: (optional) The health check port number. If specified,
               this overrides the ports specified in the server member resources.
        :param str url_path: (optional) The health check URL. This is applicable
               only to `http` type of health monitor.
        """
        self.delay = delay
        self.max_retries = max_retries
        self.port = port
        self.timeout = timeout
        self.type = type
        self.url_path = url_path

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolHealthMonitorPrototype':
        """Initialize a LoadBalancerPoolHealthMonitorPrototype object from a json dictionary."""
        args = {}
        if 'delay' in _dict:
            args['delay'] = _dict.get('delay')
        else:
            raise ValueError(
                'Required property \'delay\' not present in LoadBalancerPoolHealthMonitorPrototype JSON'
            )
        if 'max_retries' in _dict:
            args['max_retries'] = _dict.get('max_retries')
        else:
            raise ValueError(
                'Required property \'max_retries\' not present in LoadBalancerPoolHealthMonitorPrototype JSON'
            )
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        if 'timeout' in _dict:
            args['timeout'] = _dict.get('timeout')
        else:
            raise ValueError(
                'Required property \'timeout\' not present in LoadBalancerPoolHealthMonitorPrototype JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerPoolHealthMonitorPrototype JSON'
            )
        if 'url_path' in _dict:
            args['url_path'] = _dict.get('url_path')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolHealthMonitorPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'delay') and self.delay is not None:
            _dict['delay'] = self.delay
        if hasattr(self, 'max_retries') and self.max_retries is not None:
            _dict['max_retries'] = self.max_retries
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'timeout') and self.timeout is not None:
            _dict['timeout'] = self.timeout
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'url_path') and self.url_path is not None:
            _dict['url_path'] = self.url_path
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolHealthMonitorPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolHealthMonitorPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolHealthMonitorPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The protocol type of this load balancer pool health monitor.
        """
        HTTP = 'http'
        TCP = 'tcp'
        HTTPS = 'https'


class LoadBalancerPoolIdentity():
    """
    Identifies a load balancer pool by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerPoolIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerPoolIdentityById', 'LoadBalancerPoolIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerPoolIdentityByName():
    """
    LoadBalancerPoolIdentityByName.

    :attr str name: The user-defined name for this load balancer pool.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a LoadBalancerPoolIdentityByName object.

        :param str name: The user-defined name for this load balancer pool.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolIdentityByName':
        """Initialize a LoadBalancerPoolIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerPoolIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMember():
    """
    LoadBalancerPoolMember.

    :attr str id: The unique identifier for this load balancer pool member.
    :attr str href: The member's canonical URL.
    :attr int port: The port number of the application running in the server member.
    :attr int weight: (optional) Weight of the server member. This takes effect only
          when the load balancing algorithm of its belonging pool is
          `weighted_round_robin`.
    :attr str health: Health of the server member in the pool.
    :attr datetime created_at: The date and time that this member was created.
    :attr str provisioning_status: The provisioning status of this member.
    :attr LoadBalancerPoolMemberTarget target: The pool member target. Load
          balancers in the `network` family
          support instances. Load balancers in the `application` family support
          IP addresses.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 port: int,
                 health: str,
                 created_at: datetime,
                 provisioning_status: str,
                 target: 'LoadBalancerPoolMemberTarget',
                 *,
                 weight: int = None) -> None:
        """
        Initialize a LoadBalancerPoolMember object.

        :param str id: The unique identifier for this load balancer pool member.
        :param str href: The member's canonical URL.
        :param int port: The port number of the application running in the server
               member.
        :param str health: Health of the server member in the pool.
        :param datetime created_at: The date and time that this member was created.
        :param str provisioning_status: The provisioning status of this member.
        :param LoadBalancerPoolMemberTarget target: The pool member target. Load
               balancers in the `network` family
               support instances. Load balancers in the `application` family support
               IP addresses.
        :param int weight: (optional) Weight of the server member. This takes
               effect only when the load balancing algorithm of its belonging pool is
               `weighted_round_robin`.
        """
        self.id = id
        self.href = href
        self.port = port
        self.weight = weight
        self.health = health
        self.created_at = created_at
        self.provisioning_status = provisioning_status
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMember':
        """Initialize a LoadBalancerPoolMember object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPoolMember JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolMember JSON'
            )
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        else:
            raise ValueError(
                'Required property \'port\' not present in LoadBalancerPoolMember JSON'
            )
        if 'weight' in _dict:
            args['weight'] = _dict.get('weight')
        if 'health' in _dict:
            args['health'] = _dict.get('health')
        else:
            raise ValueError(
                'Required property \'health\' not present in LoadBalancerPoolMember JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in LoadBalancerPoolMember JSON'
            )
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancerPoolMember JSON'
            )
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError(
                'Required property \'target\' not present in LoadBalancerPoolMember JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMember object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'weight') and self.weight is not None:
            _dict['weight'] = self.weight
        if hasattr(self, 'health') and self.health is not None:
            _dict['health'] = self.health
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMember object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMember') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMember') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HealthEnum(str, Enum):
        """
        Health of the server member in the pool.
        """
        FAULTED = 'faulted'
        OK = 'ok'
        UNKNOWN = 'unknown'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this member.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerPoolMemberCollection():
    """
    LoadBalancerPoolMemberCollection.

    :attr List[LoadBalancerPoolMember] members: Collection of members.
    """

    def __init__(self, members: List['LoadBalancerPoolMember']) -> None:
        """
        Initialize a LoadBalancerPoolMemberCollection object.

        :param List[LoadBalancerPoolMember] members: Collection of members.
        """
        self.members = members

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberCollection':
        """Initialize a LoadBalancerPoolMemberCollection object from a json dictionary."""
        args = {}
        if 'members' in _dict:
            args['members'] = [
                LoadBalancerPoolMember.from_dict(x)
                for x in _dict.get('members')
            ]
        else:
            raise ValueError(
                'Required property \'members\' not present in LoadBalancerPoolMemberCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'members') and self.members is not None:
            _dict['members'] = [x.to_dict() for x in self.members]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberPrototype():
    """
    LoadBalancerPoolMemberPrototype.

    :attr int port: The port number of the application running in the server member.
    :attr int weight: (optional) Weight of the server member. This takes effect only
          when the load balancing algorithm of its belonging pool is
          `weighted_round_robin`.
    :attr LoadBalancerPoolMemberTargetPrototype target: The pool member target. Load
          balancers in the `network` family
          support instances. Load balancers in the `application` family support
          IP addresses.
    """

    def __init__(self,
                 port: int,
                 target: 'LoadBalancerPoolMemberTargetPrototype',
                 *,
                 weight: int = None) -> None:
        """
        Initialize a LoadBalancerPoolMemberPrototype object.

        :param int port: The port number of the application running in the server
               member.
        :param LoadBalancerPoolMemberTargetPrototype target: The pool member
               target. Load balancers in the `network` family
               support instances. Load balancers in the `application` family support
               IP addresses.
        :param int weight: (optional) Weight of the server member. This takes
               effect only when the load balancing algorithm of its belonging pool is
               `weighted_round_robin`.
        """
        self.port = port
        self.weight = weight
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberPrototype':
        """Initialize a LoadBalancerPoolMemberPrototype object from a json dictionary."""
        args = {}
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        else:
            raise ValueError(
                'Required property \'port\' not present in LoadBalancerPoolMemberPrototype JSON'
            )
        if 'weight' in _dict:
            args['weight'] = _dict.get('weight')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError(
                'Required property \'target\' not present in LoadBalancerPoolMemberPrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'weight') and self.weight is not None:
            _dict['weight'] = self.weight
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberReference():
    """
    LoadBalancerPoolMemberReference.

    :attr str id: The unique identifier for this load balancer pool member.
    :attr str href: The member's canonical URL.
    """

    def __init__(self, id: str, href: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberReference object.

        :param str id: The unique identifier for this load balancer pool member.
        :param str href: The member's canonical URL.
        """
        self.id = id
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberReference':
        """Initialize a LoadBalancerPoolMemberReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPoolMemberReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolMemberReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTarget():
    """
    The pool member target. Load balancers in the `network` family support instances. Load
    balancers in the `application` family support IP addresses.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerPoolMemberTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerPoolMemberTargetInstanceReference',
                'LoadBalancerPoolMemberTargetIP'
            ]))
        raise Exception(msg)


class LoadBalancerPoolMemberTargetPrototype():
    """
    The pool member target. Load balancers in the `network` family support instances. Load
    balancers in the `application` family support IP addresses.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerPoolMemberTargetPrototypeInstanceIdentity',
                'LoadBalancerPoolMemberTargetPrototypeIP'
            ]))
        raise Exception(msg)


class LoadBalancerPoolPrototype():
    """
    LoadBalancerPoolPrototype.

    :attr str name: (optional) The user-defined name for this load balancer pool. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str algorithm: The load balancing algorithm.
    :attr str protocol: The protocol used for this load balancer pool.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the pool on which the unexpected
          property value was encountered.
    :attr LoadBalancerPoolHealthMonitorPrototype health_monitor: The health monitor
          of this pool.
    :attr List[LoadBalancerPoolMemberPrototype] members: (optional) The members for
          this load balancer pool. For load balancers in the `network` family, the same
          `port` and `target` tuple cannot be shared by a member of any other load
          balancer.
    :attr LoadBalancerPoolSessionPersistencePrototype session_persistence:
          (optional) The session persistence of this pool.
    """

    def __init__(
        self,
        algorithm: str,
        protocol: str,
        health_monitor: 'LoadBalancerPoolHealthMonitorPrototype',
        *,
        name: str = None,
        members: List['LoadBalancerPoolMemberPrototype'] = None,
        session_persistence: 'LoadBalancerPoolSessionPersistencePrototype' = None
    ) -> None:
        """
        Initialize a LoadBalancerPoolPrototype object.

        :param str algorithm: The load balancing algorithm.
        :param str protocol: The protocol used for this load balancer pool.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the pool on
               which the unexpected property value was encountered.
        :param LoadBalancerPoolHealthMonitorPrototype health_monitor: The health
               monitor of this pool.
        :param str name: (optional) The user-defined name for this load balancer
               pool. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param List[LoadBalancerPoolMemberPrototype] members: (optional) The
               members for this load balancer pool. For load balancers in the `network`
               family, the same `port` and `target` tuple cannot be shared by a member of
               any other load balancer.
        :param LoadBalancerPoolSessionPersistencePrototype session_persistence:
               (optional) The session persistence of this pool.
        """
        self.name = name
        self.algorithm = algorithm
        self.protocol = protocol
        self.health_monitor = health_monitor
        self.members = members
        self.session_persistence = session_persistence

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolPrototype':
        """Initialize a LoadBalancerPoolPrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'algorithm' in _dict:
            args['algorithm'] = _dict.get('algorithm')
        else:
            raise ValueError(
                'Required property \'algorithm\' not present in LoadBalancerPoolPrototype JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in LoadBalancerPoolPrototype JSON'
            )
        if 'health_monitor' in _dict:
            args[
                'health_monitor'] = LoadBalancerPoolHealthMonitorPrototype.from_dict(
                    _dict.get('health_monitor'))
        else:
            raise ValueError(
                'Required property \'health_monitor\' not present in LoadBalancerPoolPrototype JSON'
            )
        if 'members' in _dict:
            args['members'] = [
                LoadBalancerPoolMemberPrototype.from_dict(x)
                for x in _dict.get('members')
            ]
        if 'session_persistence' in _dict:
            args[
                'session_persistence'] = LoadBalancerPoolSessionPersistencePrototype.from_dict(
                    _dict.get('session_persistence'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'algorithm') and self.algorithm is not None:
            _dict['algorithm'] = self.algorithm
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'health_monitor') and self.health_monitor is not None:
            _dict['health_monitor'] = self.health_monitor.to_dict()
        if hasattr(self, 'members') and self.members is not None:
            _dict['members'] = [x.to_dict() for x in self.members]
        if hasattr(
                self,
                'session_persistence') and self.session_persistence is not None:
            _dict['session_persistence'] = self.session_persistence.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AlgorithmEnum(str, Enum):
        """
        The load balancing algorithm.
        """
        LEAST_CONNECTIONS = 'least_connections'
        ROUND_ROBIN = 'round_robin'
        WEIGHTED_ROUND_ROBIN = 'weighted_round_robin'

    class ProtocolEnum(str, Enum):
        """
        The protocol used for this load balancer pool.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the pool on which the unexpected
        property value was encountered.
        """
        HTTP = 'http'
        TCP = 'tcp'
        HTTPS = 'https'


class LoadBalancerPoolReference():
    """
    LoadBalancerPoolReference.

    :attr str id: The unique identifier for this load balancer pool.
    :attr str href: The pool's canonical URL.
    :attr str name: The user-defined name for this load balancer pool.
    """

    def __init__(self, id: str, href: str, name: str) -> None:
        """
        Initialize a LoadBalancerPoolReference object.

        :param str id: The unique identifier for this load balancer pool.
        :param str href: The pool's canonical URL.
        :param str name: The user-defined name for this load balancer pool.
        """
        self.id = id
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolReference':
        """Initialize a LoadBalancerPoolReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPoolReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerPoolReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolSessionPersistence():
    """
    LoadBalancerPoolSessionPersistence.

    :attr str type: The session persistence type.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistence object.

        :param str type: The session persistence type.
        """
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolSessionPersistence':
        """Initialize a LoadBalancerPoolSessionPersistence object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerPoolSessionPersistence JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolSessionPersistence object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolSessionPersistence object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolSessionPersistence') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolSessionPersistence') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The session persistence type.
        """
        SOURCE_IP = 'source_ip'


class LoadBalancerPoolSessionPersistencePatch():
    """
    LoadBalancerPoolSessionPersistencePatch.

    :attr str type: The session persistence type.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistencePatch object.

        :param str type: The session persistence type.
        """
        self.type = type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerPoolSessionPersistencePatch':
        """Initialize a LoadBalancerPoolSessionPersistencePatch object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerPoolSessionPersistencePatch JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolSessionPersistencePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolSessionPersistencePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolSessionPersistencePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolSessionPersistencePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The session persistence type.
        """
        SOURCE_IP = 'source_ip'


class LoadBalancerPoolSessionPersistencePrototype():
    """
    LoadBalancerPoolSessionPersistencePrototype.

    :attr str type: The session persistence type.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistencePrototype object.

        :param str type: The session persistence type.
        """
        self.type = type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerPoolSessionPersistencePrototype':
        """Initialize a LoadBalancerPoolSessionPersistencePrototype object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerPoolSessionPersistencePrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolSessionPersistencePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolSessionPersistencePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'LoadBalancerPoolSessionPersistencePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'LoadBalancerPoolSessionPersistencePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The session persistence type.
        """
        SOURCE_IP = 'source_ip'


class LoadBalancerProfile():
    """
    LoadBalancerProfile.

    :attr str name: The name for this load balancer profile.
    :attr str href: The URL for this load balancer profile.
    :attr str family: The product family this load balancer profile belongs to.
    """

    def __init__(self, name: str, href: str, family: str) -> None:
        """
        Initialize a LoadBalancerProfile object.

        :param str name: The name for this load balancer profile.
        :param str href: The URL for this load balancer profile.
        :param str family: The product family this load balancer profile belongs
               to.
        """
        self.name = name
        self.href = href
        self.family = family

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfile':
        """Initialize a LoadBalancerProfile object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerProfile JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerProfile JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' not present in LoadBalancerProfile JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileCollection():
    """
    LoadBalancerProfileCollection.

    :attr LoadBalancerProfileCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr LoadBalancerProfileCollectionNext next: (optional) A reference to the next
          page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[LoadBalancerProfile] profiles: Collection of load balancer profiles.
    """

    def __init__(self,
                 first: 'LoadBalancerProfileCollectionFirst',
                 limit: int,
                 total_count: int,
                 profiles: List['LoadBalancerProfile'],
                 *,
                 next: 'LoadBalancerProfileCollectionNext' = None) -> None:
        """
        Initialize a LoadBalancerProfileCollection object.

        :param LoadBalancerProfileCollectionFirst first: A reference to the first
               page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[LoadBalancerProfile] profiles: Collection of load balancer
               profiles.
        :param LoadBalancerProfileCollectionNext next: (optional) A reference to
               the next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.profiles = profiles

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileCollection':
        """Initialize a LoadBalancerProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = LoadBalancerProfileCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in LoadBalancerProfileCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in LoadBalancerProfileCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = LoadBalancerProfileCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in LoadBalancerProfileCollection JSON'
            )
        if 'profiles' in _dict:
            args['profiles'] = [
                LoadBalancerProfile.from_dict(x) for x in _dict.get('profiles')
            ]
        else:
            raise ValueError(
                'Required property \'profiles\' not present in LoadBalancerProfileCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'profiles') and self.profiles is not None:
            _dict['profiles'] = [x.to_dict() for x in self.profiles]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerProfileCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileCollectionFirst':
        """Initialize a LoadBalancerProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerProfileCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerProfileCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileCollectionNext':
        """Initialize a LoadBalancerProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerProfileCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileIdentity():
    """
    Identifies a load balancer profile by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerProfileIdentityByName',
                'LoadBalancerProfileIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerProfileReference():
    """
    LoadBalancerProfileReference.

    :attr str name: The name for this load balancer profile.
    :attr str href: The URL for this load balancer profile.
    :attr str family: The product family this load balancer profile belongs to.
    """

    def __init__(self, name: str, href: str, family: str) -> None:
        """
        Initialize a LoadBalancerProfileReference object.

        :param str name: The name for this load balancer profile.
        :param str href: The URL for this load balancer profile.
        :param str family: The product family this load balancer profile belongs
               to.
        """
        self.name = name
        self.href = href
        self.family = family

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileReference':
        """Initialize a LoadBalancerProfileReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerProfileReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerProfileReference JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' not present in LoadBalancerProfileReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerStatistics():
    """
    LoadBalancerStatistics.

    :attr int active_connections: Number of active connections of this load
          balancer.
    :attr float connection_rate: Current connection rate (connections per second) of
          this load balancer.
    :attr int data_processed_this_month: Total number of data processed (bytes) of
          this load balancer within current calendar month.
    :attr float throughput: Current throughput (Mbps) of this load balancer.
    """

    def __init__(self, active_connections: int, connection_rate: float,
                 data_processed_this_month: int, throughput: float) -> None:
        """
        Initialize a LoadBalancerStatistics object.

        :param int active_connections: Number of active connections of this load
               balancer.
        :param float connection_rate: Current connection rate (connections per
               second) of this load balancer.
        :param int data_processed_this_month: Total number of data processed
               (bytes) of this load balancer within current calendar month.
        :param float throughput: Current throughput (Mbps) of this load balancer.
        """
        self.active_connections = active_connections
        self.connection_rate = connection_rate
        self.data_processed_this_month = data_processed_this_month
        self.throughput = throughput

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerStatistics':
        """Initialize a LoadBalancerStatistics object from a json dictionary."""
        args = {}
        if 'active_connections' in _dict:
            args['active_connections'] = _dict.get('active_connections')
        else:
            raise ValueError(
                'Required property \'active_connections\' not present in LoadBalancerStatistics JSON'
            )
        if 'connection_rate' in _dict:
            args['connection_rate'] = _dict.get('connection_rate')
        else:
            raise ValueError(
                'Required property \'connection_rate\' not present in LoadBalancerStatistics JSON'
            )
        if 'data_processed_this_month' in _dict:
            args['data_processed_this_month'] = _dict.get(
                'data_processed_this_month')
        else:
            raise ValueError(
                'Required property \'data_processed_this_month\' not present in LoadBalancerStatistics JSON'
            )
        if 'throughput' in _dict:
            args['throughput'] = _dict.get('throughput')
        else:
            raise ValueError(
                'Required property \'throughput\' not present in LoadBalancerStatistics JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerStatistics object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(
                self,
                'active_connections') and self.active_connections is not None:
            _dict['active_connections'] = self.active_connections
        if hasattr(self,
                   'connection_rate') and self.connection_rate is not None:
            _dict['connection_rate'] = self.connection_rate
        if hasattr(self, 'data_processed_this_month'
                  ) and self.data_processed_this_month is not None:
            _dict['data_processed_this_month'] = self.data_processed_this_month
        if hasattr(self, 'throughput') and self.throughput is not None:
            _dict['throughput'] = self.throughput
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerStatistics object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerStatistics') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerStatistics') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACL():
    """
    NetworkACL.

    :attr str id: The unique identifier for this network ACL.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str name: The user-defined name for this network ACL.
    :attr VPCReference vpc: The VPC this network ACL is a part of.
    :attr ResourceGroupReference resource_group: The resource group for this network
          ACL.
    :attr datetime created_at: The date and time that the network ACL was created.
    :attr List[NetworkACLRuleItem] rules: The ordered rules for this network ACL. If
          no rules exist, all traffic will be denied.
    :attr List[SubnetReference] subnets: The subnets to which this network ACL is
          attached.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 vpc: 'VPCReference', resource_group: 'ResourceGroupReference',
                 created_at: datetime, rules: List['NetworkACLRuleItem'],
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a NetworkACL object.

        :param str id: The unique identifier for this network ACL.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str name: The user-defined name for this network ACL.
        :param VPCReference vpc: The VPC this network ACL is a part of.
        :param ResourceGroupReference resource_group: The resource group for this
               network ACL.
        :param datetime created_at: The date and time that the network ACL was
               created.
        :param List[NetworkACLRuleItem] rules: The ordered rules for this network
               ACL. If no rules exist, all traffic will be denied.
        :param List[SubnetReference] subnets: The subnets to which this network ACL
               is attached.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.vpc = vpc
        self.resource_group = resource_group
        self.created_at = created_at
        self.rules = rules
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACL':
        """Initialize a NetworkACL object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACL JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in NetworkACL JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACL JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACL JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in NetworkACL JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in NetworkACL JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACL JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                NetworkACLRuleItem.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in NetworkACL JSON')
        if 'subnets' in _dict:
            args['subnets'] = [
                SubnetReference.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in NetworkACL JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'subnets') and self.subnets is not None:
            _dict['subnets'] = [x.to_dict() for x in self.subnets]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLCollection():
    """
    NetworkACLCollection.

    :attr NetworkACLCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr NetworkACLCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[NetworkACL] network_acls: Collection of network ACLs.
    """

    def __init__(self,
                 first: 'NetworkACLCollectionFirst',
                 limit: int,
                 total_count: int,
                 network_acls: List['NetworkACL'],
                 *,
                 next: 'NetworkACLCollectionNext' = None) -> None:
        """
        Initialize a NetworkACLCollection object.

        :param NetworkACLCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[NetworkACL] network_acls: Collection of network ACLs.
        :param NetworkACLCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.network_acls = network_acls

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLCollection':
        """Initialize a NetworkACLCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = NetworkACLCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in NetworkACLCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in NetworkACLCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = NetworkACLCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in NetworkACLCollection JSON'
            )
        if 'network_acls' in _dict:
            args['network_acls'] = [
                NetworkACL.from_dict(x) for x in _dict.get('network_acls')
            ]
        else:
            raise ValueError(
                'Required property \'network_acls\' not present in NetworkACLCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'network_acls') and self.network_acls is not None:
            _dict['network_acls'] = [x.to_dict() for x in self.network_acls]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLCollectionFirst':
        """Initialize a NetworkACLCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLCollectionNext':
        """Initialize a NetworkACLCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentity():
    """
    Identifies a network ACL by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a NetworkACLIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLIdentityById', 'NetworkACLIdentityByCRN',
                'NetworkACLIdentityByHref'
            ]))
        raise Exception(msg)


class NetworkACLPrototype():
    """
    NetworkACLPrototype.

    :attr str name: (optional) The user-defined name for this network ACL. Names
          must be unique within the VPC the Network ACL resides in. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr VPCIdentity vpc: The VPC this network ACL is to be a part of.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a NetworkACLPrototype object.

        :param VPCIdentity vpc: The VPC this network ACL is to be a part of.
        :param str name: (optional) The user-defined name for this network ACL.
               Names must be unique within the VPC the Network ACL resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLPrototypeNetworkACLByRules',
                'NetworkACLPrototypeNetworkACLBySourceNetworkACL'
            ]))
        raise Exception(msg)


class NetworkACLReference():
    """
    NetworkACLReference.

    :attr str id: The unique identifier for this network ACL.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str name: The user-defined name for this network ACL.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a NetworkACLReference object.

        :param str id: The unique identifier for this network ACL.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str name: The user-defined name for this network ACL.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLReference':
        """Initialize a NetworkACLReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in NetworkACLReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRule():
    """
    NetworkACLRule.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRule object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. If absent, this is the last rule.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRuleNetworkACLRuleProtocolTCPUDP',
                'NetworkACLRuleNetworkACLRuleProtocolICMP',
                'NetworkACLRuleNetworkACLRuleProtocolAll'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRule':
        """Initialize a NetworkACLRule object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = (
            "Cannot convert dictionary into an instance of base class 'NetworkACLRule'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'NetworkACLRuleNetworkACLRuleProtocolTCPUDP',
            'NetworkACLRuleNetworkACLRuleProtocolICMP',
            'NetworkACLRuleNetworkACLRuleProtocolAll'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a NetworkACLRule object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['all'] = 'NetworkACLRuleNetworkACLRuleProtocolAll'
        mapping['icmp'] = 'NetworkACLRuleNetworkACLRuleProtocolICMP'
        mapping['tcp'] = 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP'
        mapping['udp'] = 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in NetworkACLRule JSON'
            )
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRuleCollection():
    """
    NetworkACLRuleCollection.

    :attr NetworkACLRuleCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr NetworkACLRuleCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[NetworkACLRuleItem] rules: Ordered collection of Network ACL rules.
    """

    def __init__(self,
                 first: 'NetworkACLRuleCollectionFirst',
                 limit: int,
                 total_count: int,
                 rules: List['NetworkACLRuleItem'],
                 *,
                 next: 'NetworkACLRuleCollectionNext' = None) -> None:
        """
        Initialize a NetworkACLRuleCollection object.

        :param NetworkACLRuleCollectionFirst first: A reference to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[NetworkACLRuleItem] rules: Ordered collection of Network ACL
               rules.
        :param NetworkACLRuleCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleCollection':
        """Initialize a NetworkACLRuleCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = NetworkACLRuleCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in NetworkACLRuleCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in NetworkACLRuleCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = NetworkACLRuleCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in NetworkACLRuleCollection JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                NetworkACLRuleItem.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in NetworkACLRuleCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleCollectionFirst':
        """Initialize a NetworkACLRuleCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleCollectionNext':
        """Initialize a NetworkACLRuleCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleIdentity():
    """
    Identifies a network ACL rule by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a NetworkACLRuleIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(
                ['NetworkACLRuleIdentityById', 'NetworkACLRuleIdentityByHref']))
        raise Exception(msg)


class NetworkACLRuleItem():
    """
    NetworkACLRuleItem.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always
          refers to the next item in the collection. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRuleItem object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. In a rule collection, this always
               refers to the next item in the collection. If absent, this is the last
               rule.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP',
                'NetworkACLRuleItemNetworkACLRuleProtocolICMP',
                'NetworkACLRuleItemNetworkACLRuleProtocolAll'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleItem':
        """Initialize a NetworkACLRuleItem object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = (
            "Cannot convert dictionary into an instance of base class 'NetworkACLRuleItem'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP',
            'NetworkACLRuleItemNetworkACLRuleProtocolICMP',
            'NetworkACLRuleItemNetworkACLRuleProtocolAll'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a NetworkACLRuleItem object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['all'] = 'NetworkACLRuleItemNetworkACLRuleProtocolAll'
        mapping['icmp'] = 'NetworkACLRuleItemNetworkACLRuleProtocolICMP'
        mapping['tcp'] = 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP'
        mapping['udp'] = 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in NetworkACLRuleItem JSON'
            )
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRulePrototype():
    """
    NetworkACLRulePrototype.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleIdentity before: (optional) The rule to insert this rule
          immediately before. If omitted, this rule will be
          inserted after all existing rules.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None,
                 before: 'NetworkACLRuleIdentity' = None) -> None:
        """
        Initialize a NetworkACLRulePrototype object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLRuleIdentity before: (optional) The rule to insert this
               rule immediately before. If omitted, this rule will be
               inserted after all existing rules.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP',
                'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP',
                'NetworkACLRulePrototypeNetworkACLRuleProtocolAll'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePrototype':
        """Initialize a NetworkACLRulePrototype object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = (
            "Cannot convert dictionary into an instance of base class 'NetworkACLRulePrototype'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP',
            'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP',
            'NetworkACLRulePrototypeNetworkACLRuleProtocolAll'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a NetworkACLRulePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['all'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolAll'
        mapping['icmp'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP'
        mapping['tcp'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP'
        mapping['udp'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in NetworkACLRulePrototype JSON'
            )
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLContext():
    """
    NetworkACLRulePrototypeNetworkACLContext.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContext object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP',
                'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP',
                'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLContext':
        """Initialize a NetworkACLRulePrototypeNetworkACLContext object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = (
            "Cannot convert dictionary into an instance of base class 'NetworkACLRulePrototypeNetworkACLContext'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP',
            'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP',
            'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLContext object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping[
            'all'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll'
        mapping[
            'icmp'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP'
        mapping[
            'tcp'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP'
        mapping[
            'udp'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in NetworkACLRulePrototypeNetworkACLContext JSON'
            )
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRuleReference():
    """
    NetworkACLRuleReference.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this Network ACL rule.
    """

    def __init__(self, id: str, href: str, name: str) -> None:
        """
        Initialize a NetworkACLRuleReference object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this Network ACL rule.
        """
        self.id = id
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleReference':
        """Initialize a NetworkACLRuleReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterface():
    """
    NetworkInterface.

    :attr str name: The user-defined name for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str href: The URL for this network interface.
    :attr str primary_ipv4_address: The primary IPv4 address.
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: Collection of security
          groups.
    :attr datetime created_at: The date and time that the network interface was
          created.
    :attr List[FloatingIPReference] floating_ips: (optional) Array of references to
          floating IPs associated with this network interface.
    :attr int port_speed: The network interface port speed in Mbps.
    :attr str status: The status of the network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The type of this network interface as it relates to an instance.
    """

    def __init__(self,
                 name: str,
                 id: str,
                 href: str,
                 primary_ipv4_address: str,
                 resource_type: str,
                 security_groups: List['SecurityGroupReference'],
                 created_at: datetime,
                 port_speed: int,
                 status: str,
                 subnet: 'SubnetReference',
                 type: str,
                 *,
                 floating_ips: List['FloatingIPReference'] = None) -> None:
        """
        Initialize a NetworkInterface object.

        :param str name: The user-defined name for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str href: The URL for this network interface.
        :param str primary_ipv4_address: The primary IPv4 address.
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: Collection of security
               groups.
        :param datetime created_at: The date and time that the network interface
               was created.
        :param int port_speed: The network interface port speed in Mbps.
        :param str status: The status of the network interface.
        :param SubnetReference subnet: The associated subnet.
        :param str type: The type of this network interface as it relates to an
               instance.
        :param List[FloatingIPReference] floating_ips: (optional) Array of
               references to floating IPs associated with this network interface.
        """
        self.name = name
        self.id = id
        self.href = href
        self.primary_ipv4_address = primary_ipv4_address
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.created_at = created_at
        self.floating_ips = floating_ips
        self.port_speed = port_speed
        self.status = status
        self.subnet = subnet
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterface':
        """Initialize a NetworkInterface object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkInterface JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkInterface JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkInterface JSON'
            )
        if 'primary_ipv4_address' in _dict:
            args['primary_ipv4_address'] = _dict.get('primary_ipv4_address')
        else:
            raise ValueError(
                'Required property \'primary_ipv4_address\' not present in NetworkInterface JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in NetworkInterface JSON'
            )
        if 'security_groups' in _dict:
            args['security_groups'] = [
                SecurityGroupReference.from_dict(x)
                for x in _dict.get('security_groups')
            ]
        else:
            raise ValueError(
                'Required property \'security_groups\' not present in NetworkInterface JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkInterface JSON'
            )
        if 'floating_ips' in _dict:
            args['floating_ips'] = [
                FloatingIPReference.from_dict(x)
                for x in _dict.get('floating_ips')
            ]
        if 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError(
                'Required property \'port_speed\' not present in NetworkInterface JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in NetworkInterface JSON'
            )
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError(
                'Required property \'subnet\' not present in NetworkInterface JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in NetworkInterface JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterface object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'primary_ipv4_address'
                  ) and self.primary_ipv4_address is not None:
            _dict['primary_ipv4_address'] = self.primary_ipv4_address
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self,
                   'security_groups') and self.security_groups is not None:
            _dict['security_groups'] = [
                x.to_dict() for x in self.security_groups
            ]
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            _dict['floating_ips'] = [x.to_dict() for x in self.floating_ips]
        if hasattr(self, 'port_speed') and self.port_speed is not None:
            _dict['port_speed'] = self.port_speed
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'subnet') and self.subnet is not None:
            _dict['subnet'] = self.subnet.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        NETWORK_INTERFACE = 'network_interface'

    class StatusEnum(str, Enum):
        """
        The status of the network interface.
        """
        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'

    class TypeEnum(str, Enum):
        """
        The type of this network interface as it relates to an instance.
        """
        PRIMARY = 'primary'
        SECONDARY = 'secondary'


class NetworkInterfaceCollection():
    """
    NetworkInterfaceCollection.

    :attr NetworkInterfaceCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr NetworkInterfaceCollectionNext next: (optional) A reference to the next
          page of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[NetworkInterface] network_interfaces: Collection of network
          interfaces.
    """

    def __init__(self,
                 first: 'NetworkInterfaceCollectionFirst',
                 limit: int,
                 total_count: int,
                 network_interfaces: List['NetworkInterface'],
                 *,
                 next: 'NetworkInterfaceCollectionNext' = None) -> None:
        """
        Initialize a NetworkInterfaceCollection object.

        :param NetworkInterfaceCollectionFirst first: A reference to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[NetworkInterface] network_interfaces: Collection of network
               interfaces.
        :param NetworkInterfaceCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.network_interfaces = network_interfaces

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceCollection':
        """Initialize a NetworkInterfaceCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = NetworkInterfaceCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in NetworkInterfaceCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in NetworkInterfaceCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = NetworkInterfaceCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in NetworkInterfaceCollection JSON'
            )
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterface.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        else:
            raise ValueError(
                'Required property \'network_interfaces\' not present in NetworkInterfaceCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkInterfaceCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceCollectionFirst':
        """Initialize a NetworkInterfaceCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkInterfaceCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkInterfaceCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceCollectionNext':
        """Initialize a NetworkInterfaceCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkInterfaceCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceInstanceContextReference():
    """
    NetworkInterfaceInstanceContextReference.

    :attr str name: The user-defined name for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str href: The URL for this network interface.
    :attr str primary_ipv4_address: The primary IPv4 address.
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet: The associated subnet.
    """

    def __init__(self, name: str, id: str, href: str, primary_ipv4_address: str,
                 resource_type: str, subnet: 'SubnetReference') -> None:
        """
        Initialize a NetworkInterfaceInstanceContextReference object.

        :param str name: The user-defined name for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str href: The URL for this network interface.
        :param str primary_ipv4_address: The primary IPv4 address.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The associated subnet.
        """
        self.name = name
        self.id = id
        self.href = href
        self.primary_ipv4_address = primary_ipv4_address
        self.resource_type = resource_type
        self.subnet = subnet

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkInterfaceInstanceContextReference':
        """Initialize a NetworkInterfaceInstanceContextReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkInterfaceInstanceContextReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkInterfaceInstanceContextReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkInterfaceInstanceContextReference JSON'
            )
        if 'primary_ipv4_address' in _dict:
            args['primary_ipv4_address'] = _dict.get('primary_ipv4_address')
        else:
            raise ValueError(
                'Required property \'primary_ipv4_address\' not present in NetworkInterfaceInstanceContextReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in NetworkInterfaceInstanceContextReference JSON'
            )
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError(
                'Required property \'subnet\' not present in NetworkInterfaceInstanceContextReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceInstanceContextReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'primary_ipv4_address'
                  ) and self.primary_ipv4_address is not None:
            _dict['primary_ipv4_address'] = self.primary_ipv4_address
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'subnet') and self.subnet is not None:
            _dict['subnet'] = self.subnet.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceInstanceContextReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceInstanceContextReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceInstanceContextReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        NETWORK_INTERFACE = 'network_interface'


class NetworkInterfacePrototype():
    """
    NetworkInterfacePrototype.

    :attr str name: (optional) The user-defined name for this network interface. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str primary_ipv4_address: (optional) The primary IPv4 address. If
          specified, it must be an available address on the network interface's subnet. If
          unspecified, an available address on the subnet will be automatically selected.
    :attr List[SecurityGroupIdentity] security_groups: (optional) Collection of
          security groups.
    :attr SubnetIdentity subnet: The associated subnet.
    """

    def __init__(self,
                 subnet: 'SubnetIdentity',
                 *,
                 name: str = None,
                 primary_ipv4_address: str = None,
                 security_groups: List['SecurityGroupIdentity'] = None) -> None:
        """
        Initialize a NetworkInterfacePrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param str name: (optional) The user-defined name for this network
               interface. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str primary_ipv4_address: (optional) The primary IPv4 address. If
               specified, it must be an available address on the network interface's
               subnet. If unspecified, an available address on the subnet will be
               automatically selected.
        :param List[SecurityGroupIdentity] security_groups: (optional) Collection
               of security groups.
        """
        self.name = name
        self.primary_ipv4_address = primary_ipv4_address
        self.security_groups = security_groups
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfacePrototype':
        """Initialize a NetworkInterfacePrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ipv4_address' in _dict:
            args['primary_ipv4_address'] = _dict.get('primary_ipv4_address')
        if 'security_groups' in _dict:
            args['security_groups'] = _dict.get('security_groups')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError(
                'Required property \'subnet\' not present in NetworkInterfacePrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfacePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ipv4_address'
                  ) and self.primary_ipv4_address is not None:
            _dict['primary_ipv4_address'] = self.primary_ipv4_address
        if hasattr(self,
                   'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for x in self.security_groups:
                if isinstance(x, dict):
                    security_groups_list.append(x)
                else:
                    security_groups_list.append(x.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfacePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfacePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfacePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceReference():
    """
    NetworkInterfaceReference.

    :attr str name: The user-defined name for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str href: The URL for this network interface.
    :attr str primary_ipv4_address: The primary IPv4 address.
    :attr str resource_type: The resource type.
    """

    def __init__(self, name: str, id: str, href: str, primary_ipv4_address: str,
                 resource_type: str) -> None:
        """
        Initialize a NetworkInterfaceReference object.

        :param str name: The user-defined name for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str href: The URL for this network interface.
        :param str primary_ipv4_address: The primary IPv4 address.
        :param str resource_type: The resource type.
        """
        self.name = name
        self.id = id
        self.href = href
        self.primary_ipv4_address = primary_ipv4_address
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceReference':
        """Initialize a NetworkInterfaceReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkInterfaceReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkInterfaceReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkInterfaceReference JSON'
            )
        if 'primary_ipv4_address' in _dict:
            args['primary_ipv4_address'] = _dict.get('primary_ipv4_address')
        else:
            raise ValueError(
                'Required property \'primary_ipv4_address\' not present in NetworkInterfaceReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in NetworkInterfaceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'primary_ipv4_address'
                  ) and self.primary_ipv4_address is not None:
            _dict['primary_ipv4_address'] = self.primary_ipv4_address
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        NETWORK_INTERFACE = 'network_interface'


class NetworkInterfaceUnpaginatedCollection():
    """
    NetworkInterfaceUnpaginatedCollection.

    :attr List[NetworkInterface] network_interfaces: Collection of network
          interfaces.
    """

    def __init__(self, network_interfaces: List['NetworkInterface']) -> None:
        """
        Initialize a NetworkInterfaceUnpaginatedCollection object.

        :param List[NetworkInterface] network_interfaces: Collection of network
               interfaces.
        """
        self.network_interfaces = network_interfaces

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceUnpaginatedCollection':
        """Initialize a NetworkInterfaceUnpaginatedCollection object from a json dictionary."""
        args = {}
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterface.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        else:
            raise ValueError(
                'Required property \'network_interfaces\' not present in NetworkInterfaceUnpaginatedCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceUnpaginatedCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceUnpaginatedCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceUnpaginatedCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceUnpaginatedCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystem():
    """
    OperatingSystem.

    :attr str name: The unique name of the operating system.
    :attr str href: The URL for this operating system.
    :attr str architecture: The operating system architecture.
    :attr str display_name: A unique, display-friendly name for the operating
          system.
    :attr str family: The name of the software family this operating system belongs
          to.
    :attr str vendor: The vendor of the operating system.
    :attr str version: The major release version of this operating system.
    """

    def __init__(self, name: str, href: str, architecture: str,
                 display_name: str, family: str, vendor: str,
                 version: str) -> None:
        """
        Initialize a OperatingSystem object.

        :param str name: The unique name of the operating system.
        :param str href: The URL for this operating system.
        :param str architecture: The operating system architecture.
        :param str display_name: A unique, display-friendly name for the operating
               system.
        :param str family: The name of the software family this operating system
               belongs to.
        :param str vendor: The vendor of the operating system.
        :param str version: The major release version of this operating system.
        """
        self.name = name
        self.href = href
        self.architecture = architecture
        self.display_name = display_name
        self.family = family
        self.vendor = vendor
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystem':
        """Initialize a OperatingSystem object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in OperatingSystem JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in OperatingSystem JSON'
            )
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError(
                'Required property \'architecture\' not present in OperatingSystem JSON'
            )
        if 'display_name' in _dict:
            args['display_name'] = _dict.get('display_name')
        else:
            raise ValueError(
                'Required property \'display_name\' not present in OperatingSystem JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' not present in OperatingSystem JSON'
            )
        if 'vendor' in _dict:
            args['vendor'] = _dict.get('vendor')
        else:
            raise ValueError(
                'Required property \'vendor\' not present in OperatingSystem JSON'
            )
        if 'version' in _dict:
            args['version'] = _dict.get('version')
        else:
            raise ValueError(
                'Required property \'version\' not present in OperatingSystem JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystem object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'architecture') and self.architecture is not None:
            _dict['architecture'] = self.architecture
        if hasattr(self, 'display_name') and self.display_name is not None:
            _dict['display_name'] = self.display_name
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'vendor') and self.vendor is not None:
            _dict['vendor'] = self.vendor
        if hasattr(self, 'version') and self.version is not None:
            _dict['version'] = self.version
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystemCollection():
    """
    OperatingSystemCollection.

    :attr OperatingSystemCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr OperatingSystemCollectionNext next: (optional) A reference to the next
          page of resources; this reference is included for all pages
          except the last page.
    :attr List[OperatingSystem] operating_systems: Collection of operating systems.
    """

    def __init__(self,
                 first: 'OperatingSystemCollectionFirst',
                 limit: int,
                 operating_systems: List['OperatingSystem'],
                 *,
                 next: 'OperatingSystemCollectionNext' = None) -> None:
        """
        Initialize a OperatingSystemCollection object.

        :param OperatingSystemCollectionFirst first: A reference to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[OperatingSystem] operating_systems: Collection of operating
               systems.
        :param OperatingSystemCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.operating_systems = operating_systems

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystemCollection':
        """Initialize a OperatingSystemCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = OperatingSystemCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in OperatingSystemCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in OperatingSystemCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = OperatingSystemCollectionNext.from_dict(
                _dict.get('next'))
        if 'operating_systems' in _dict:
            args['operating_systems'] = [
                OperatingSystem.from_dict(x)
                for x in _dict.get('operating_systems')
            ]
        else:
            raise ValueError(
                'Required property \'operating_systems\' not present in OperatingSystemCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystemCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self,
                   'operating_systems') and self.operating_systems is not None:
            _dict['operating_systems'] = [
                x.to_dict() for x in self.operating_systems
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystemCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystemCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystemCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystemCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a OperatingSystemCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystemCollectionFirst':
        """Initialize a OperatingSystemCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in OperatingSystemCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystemCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystemCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystemCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystemCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystemCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a OperatingSystemCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystemCollectionNext':
        """Initialize a OperatingSystemCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in OperatingSystemCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystemCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystemCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystemCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystemCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystemIdentity():
    """
    Identifies an operating system by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a OperatingSystemIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'OperatingSystemIdentityByName', 'OperatingSystemIdentityByHref'
            ]))
        raise Exception(msg)


class PublicGateway():
    """
    PublicGateway.

    :attr str id: The unique identifier for this public gateway.
    :attr str crn: The CRN for this public gateway.
    :attr str href: The URL for this public gateway.
    :attr str name: The user-defined name for this public gateway.
    :attr str resource_type: The resource type.
    :attr ResourceGroupReference resource_group: The resource group for this public
          gateway.
    :attr datetime created_at: The date and time that the public gateway was
          created.
    :attr PublicGatewayFloatingIp floating_ip: Reference to the floating IP which is
          bound to this public gateway.
    :attr str status: The status of the volume.
    :attr VPCReference vpc: The VPC this public gateway serves.
    :attr ZoneReference zone: The zone where this public gateway lives.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 resource_type: str, resource_group: 'ResourceGroupReference',
                 created_at: datetime, floating_ip: 'PublicGatewayFloatingIp',
                 status: str, vpc: 'VPCReference',
                 zone: 'ZoneReference') -> None:
        """
        Initialize a PublicGateway object.

        :param str id: The unique identifier for this public gateway.
        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str name: The user-defined name for this public gateway.
        :param str resource_type: The resource type.
        :param ResourceGroupReference resource_group: The resource group for this
               public gateway.
        :param datetime created_at: The date and time that the public gateway was
               created.
        :param PublicGatewayFloatingIp floating_ip: Reference to the floating IP
               which is bound to this public gateway.
        :param str status: The status of the volume.
        :param VPCReference vpc: The VPC this public gateway serves.
        :param ZoneReference zone: The zone where this public gateway lives.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_type = resource_type
        self.resource_group = resource_group
        self.created_at = created_at
        self.floating_ip = floating_ip
        self.status = status
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGateway':
        """Initialize a PublicGateway object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in PublicGateway JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGateway JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGateway JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in PublicGateway JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in PublicGateway JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in PublicGateway JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in PublicGateway JSON'
            )
        if 'floating_ip' in _dict:
            args['floating_ip'] = PublicGatewayFloatingIp.from_dict(
                _dict.get('floating_ip'))
        else:
            raise ValueError(
                'Required property \'floating_ip\' not present in PublicGateway JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in PublicGateway JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in PublicGateway JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in PublicGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGateway object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'floating_ip') and self.floating_ip is not None:
            _dict['floating_ip'] = self.floating_ip.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGateway object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGateway') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGateway') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        PUBLIC_GATEWAY = 'public_gateway'

    class StatusEnum(str, Enum):
        """
        The status of the volume.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


class PublicGatewayCollection():
    """
    PublicGatewayCollection.

    :attr PublicGatewayCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr PublicGatewayCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[PublicGateway] public_gateways: Collection of public gateways.
    """

    def __init__(self,
                 first: 'PublicGatewayCollectionFirst',
                 limit: int,
                 total_count: int,
                 public_gateways: List['PublicGateway'],
                 *,
                 next: 'PublicGatewayCollectionNext' = None) -> None:
        """
        Initialize a PublicGatewayCollection object.

        :param PublicGatewayCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[PublicGateway] public_gateways: Collection of public gateways.
        :param PublicGatewayCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.public_gateways = public_gateways

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayCollection':
        """Initialize a PublicGatewayCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = PublicGatewayCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in PublicGatewayCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in PublicGatewayCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = PublicGatewayCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in PublicGatewayCollection JSON'
            )
        if 'public_gateways' in _dict:
            args['public_gateways'] = [
                PublicGateway.from_dict(x) for x in _dict.get('public_gateways')
            ]
        else:
            raise ValueError(
                'Required property \'public_gateways\' not present in PublicGatewayCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self,
                   'public_gateways') and self.public_gateways is not None:
            _dict['public_gateways'] = [
                x.to_dict() for x in self.public_gateways
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayCollectionFirst':
        """Initialize a PublicGatewayCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayCollectionNext':
        """Initialize a PublicGatewayCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIp():
    """
    Reference to the floating IP which is bound to this public gateway.

    :attr str id: The unique identifier for this floating IP.
    :attr str crn: The CRN for this floating IP.
    :attr str href: The URL for this floating IP.
    :attr str address: The globally unique IP address.
    :attr str name: The unique user-defined name for this floating IP.
    """

    def __init__(self, id: str, crn: str, href: str, address: str,
                 name: str) -> None:
        """
        Initialize a PublicGatewayFloatingIp object.

        :param str id: The unique identifier for this floating IP.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str address: The globally unique IP address.
        :param str name: The unique user-defined name for this floating IP.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.address = address
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIp':
        """Initialize a PublicGatewayFloatingIp object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in PublicGatewayFloatingIp JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGatewayFloatingIp JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayFloatingIp JSON'
            )
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in PublicGatewayFloatingIp JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in PublicGatewayFloatingIp JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIp object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIp object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIp') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIp') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentity():
    """
    Identifies a public gateway by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a PublicGatewayIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'PublicGatewayIdentityById', 'PublicGatewayIdentityByCRN',
                'PublicGatewayIdentityByHref'
            ]))
        raise Exception(msg)


class PublicGatewayPrototypeFloatingIp():
    """
    PublicGatewayPrototypeFloatingIp.

    """

    def __init__(self) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIp object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'PublicGatewayPrototypeFloatingIpFloatingIPIdentity',
                'PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext'
            ]))
        raise Exception(msg)


class PublicGatewayReference():
    """
    PublicGatewayReference.

    :attr str id: The unique identifier for this public gateway.
    :attr str crn: The CRN for this public gateway.
    :attr str href: The URL for this public gateway.
    :attr str name: The user-defined name for this public gateway.
    :attr str resource_type: The resource type.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 resource_type: str) -> None:
        """
        Initialize a PublicGatewayReference object.

        :param str id: The unique identifier for this public gateway.
        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str name: The user-defined name for this public gateway.
        :param str resource_type: The resource type.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayReference':
        """Initialize a PublicGatewayReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in PublicGatewayReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGatewayReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in PublicGatewayReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in PublicGatewayReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        PUBLIC_GATEWAY = 'public_gateway'


class Region():
    """
    Region.

    :attr str name: The name for this region.
    :attr str href: The URL for this region.
    :attr str endpoint: The API endpoint for this region.
    :attr str status: The availability status of this region.
    """

    def __init__(self, name: str, href: str, endpoint: str,
                 status: str) -> None:
        """
        Initialize a Region object.

        :param str name: The name for this region.
        :param str href: The URL for this region.
        :param str endpoint: The API endpoint for this region.
        :param str status: The availability status of this region.
        """
        self.name = name
        self.href = href
        self.endpoint = endpoint
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Region':
        """Initialize a Region object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Region JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Region JSON')
        if 'endpoint' in _dict:
            args['endpoint'] = _dict.get('endpoint')
        else:
            raise ValueError(
                'Required property \'endpoint\' not present in Region JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Region JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Region object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'endpoint') and self.endpoint is not None:
            _dict['endpoint'] = self.endpoint
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Region object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Region') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Region') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The availability status of this region.
        """
        AVAILABLE = 'available'
        UNAVAILABLE = 'unavailable'


class RegionCollection():
    """
    RegionCollection.

    :attr List[Region] regions: Array of Region objects.
    """

    def __init__(self, regions: List['Region']) -> None:
        """
        Initialize a RegionCollection object.

        :param List[Region] regions: Array of Region objects.
        """
        self.regions = regions

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionCollection':
        """Initialize a RegionCollection object from a json dictionary."""
        args = {}
        if 'regions' in _dict:
            args['regions'] = [
                Region.from_dict(x) for x in _dict.get('regions')
            ]
        else:
            raise ValueError(
                'Required property \'regions\' not present in RegionCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RegionCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'regions') and self.regions is not None:
            _dict['regions'] = [x.to_dict() for x in self.regions]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RegionCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RegionCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RegionCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RegionReference():
    """
    RegionReference.

    :attr str name: The name for this region.
    :attr str href: The URL for this region.
    """

    def __init__(self, name: str, href: str) -> None:
        """
        Initialize a RegionReference object.

        :param str name: The name for this region.
        :param str href: The URL for this region.
        """
        self.name = name
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionReference':
        """Initialize a RegionReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in RegionReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RegionReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RegionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RegionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RegionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RegionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ResourceGroupIdentity():
    """
    The resource group to use. If unspecified, the account's [default resource
    group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.

    """

    def __init__(self) -> None:
        """
        Initialize a ResourceGroupIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ResourceGroupIdentityById']))
        raise Exception(msg)


class ResourceGroupReference():
    """
    ResourceGroupReference.

    :attr str id: The unique identifier for this resource group.
    :attr str name: The user-defined name for this resource group.
    :attr str href: The URL for this resource group.
    """

    def __init__(self, id: str, name: str, href: str) -> None:
        """
        Initialize a ResourceGroupReference object.

        :param str id: The unique identifier for this resource group.
        :param str name: The user-defined name for this resource group.
        :param str href: The URL for this resource group.
        """
        self.id = id
        self.name = name
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ResourceGroupReference':
        """Initialize a ResourceGroupReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ResourceGroupReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ResourceGroupReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ResourceGroupReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ResourceGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ResourceGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ResourceGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ResourceGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Route():
    """
    Route.

    :attr RouteNextHop next_hop: The next hop that packets will be delivered to.
    :attr str id: The unique identifier for this route.
    :attr str href: The URL for this route.
    :attr str name: The user-defined name for this route.
    :attr datetime created_at: The date and time that the route was created.
    :attr str destination: The destination of the route.
    :attr str lifecycle_state: The lifecycle state of the route.
    :attr ZoneReference zone: The zone the route applies to. (Traffic from subnets
          in this zone will be
          subject to this route.).
    """

    def __init__(self, next_hop: 'RouteNextHop', id: str, href: str, name: str,
                 created_at: datetime, destination: str, lifecycle_state: str,
                 zone: 'ZoneReference') -> None:
        """
        Initialize a Route object.

        :param RouteNextHop next_hop: The next hop that packets will be delivered
               to.
        :param str id: The unique identifier for this route.
        :param str href: The URL for this route.
        :param str name: The user-defined name for this route.
        :param datetime created_at: The date and time that the route was created.
        :param str destination: The destination of the route.
        :param str lifecycle_state: The lifecycle state of the route.
        :param ZoneReference zone: The zone the route applies to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        """
        self.next_hop = next_hop
        self.id = id
        self.href = href
        self.name = name
        self.created_at = created_at
        self.destination = destination
        self.lifecycle_state = lifecycle_state
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Route':
        """Initialize a Route object from a json dictionary."""
        args = {}
        if 'next_hop' in _dict:
            args['next_hop'] = _dict.get('next_hop')
        else:
            raise ValueError(
                'Required property \'next_hop\' not present in Route JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Route JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Route JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Route JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in Route JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in Route JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' not present in Route JSON'
            )
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in Route JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Route object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'next_hop') and self.next_hop is not None:
            if isinstance(self.next_hop, dict):
                _dict['next_hop'] = self.next_hop
            else:
                _dict['next_hop'] = self.next_hop.to_dict()
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Route object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Route') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Route') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the route.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'


class RouteCollection():
    """
    RouteCollection.

    :attr List[Route] routes: Collection of routes.
    """

    def __init__(self, routes: List['Route']) -> None:
        """
        Initialize a RouteCollection object.

        :param List[Route] routes: Collection of routes.
        """
        self.routes = routes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollection':
        """Initialize a RouteCollection object from a json dictionary."""
        args = {}
        if 'routes' in _dict:
            args['routes'] = [Route.from_dict(x) for x in _dict.get('routes')]
        else:
            raise ValueError(
                'Required property \'routes\' not present in RouteCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'routes') and self.routes is not None:
            _dict['routes'] = [x.to_dict() for x in self.routes]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHop():
    """
    RouteNextHop.

    """

    def __init__(self) -> None:
        """
        Initialize a RouteNextHop object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopIP']))
        raise Exception(msg)


class RouteNextHopPrototype():
    """
    The next hop packets will be routed to.

    """

    def __init__(self) -> None:
        """
        Initialize a RouteNextHopPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopPrototypeRouteNextHopIP']))
        raise Exception(msg)


class SecurityGroup():
    """
    SecurityGroup.

    :attr str id: The unique identifier for this security group.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str name: The user-defined name for this security group. Names must be
          unique within the VPC the security group resides in.
    :attr ResourceGroupReference resource_group: The resource group for this
          security group.
    :attr datetime created_at: The date and time that this security group was
          created.
    :attr List[NetworkInterfaceReference] network_interfaces: Array of references to
          network interfaces.
    :attr List[SecurityGroupRule] rules: Array of rules for this security group. If
          no rules exist, all traffic will be denied.
    :attr VPCReference vpc: The VPC this security group is a part of.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 resource_group: 'ResourceGroupReference', created_at: datetime,
                 network_interfaces: List['NetworkInterfaceReference'],
                 rules: List['SecurityGroupRule'], vpc: 'VPCReference') -> None:
        """
        Initialize a SecurityGroup object.

        :param str id: The unique identifier for this security group.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str name: The user-defined name for this security group. Names must
               be unique within the VPC the security group resides in.
        :param ResourceGroupReference resource_group: The resource group for this
               security group.
        :param datetime created_at: The date and time that this security group was
               created.
        :param List[NetworkInterfaceReference] network_interfaces: Array of
               references to network interfaces.
        :param List[SecurityGroupRule] rules: Array of rules for this security
               group. If no rules exist, all traffic will be denied.
        :param VPCReference vpc: The VPC this security group is a part of.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_group = resource_group
        self.created_at = created_at
        self.network_interfaces = network_interfaces
        self.rules = rules
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroup':
        """Initialize a SecurityGroup object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in SecurityGroup JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in SecurityGroup JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in SecurityGroup JSON'
            )
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfaceReference.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        else:
            raise ValueError(
                'Required property \'network_interfaces\' not present in SecurityGroup JSON'
            )
        if 'rules' in _dict:
            args['rules'] = [
                SecurityGroupRule.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in SecurityGroup JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in SecurityGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupCollection():
    """
    SecurityGroupCollection.

    :attr SecurityGroupCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr SecurityGroupCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[SecurityGroup] security_groups: Collection of security groups.
    """

    def __init__(self,
                 first: 'SecurityGroupCollectionFirst',
                 limit: int,
                 total_count: int,
                 security_groups: List['SecurityGroup'],
                 *,
                 next: 'SecurityGroupCollectionNext' = None) -> None:
        """
        Initialize a SecurityGroupCollection object.

        :param SecurityGroupCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[SecurityGroup] security_groups: Collection of security groups.
        :param SecurityGroupCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.security_groups = security_groups

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupCollection':
        """Initialize a SecurityGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SecurityGroupCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in SecurityGroupCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in SecurityGroupCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = SecurityGroupCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in SecurityGroupCollection JSON'
            )
        if 'security_groups' in _dict:
            args['security_groups'] = [
                SecurityGroup.from_dict(x) for x in _dict.get('security_groups')
            ]
        else:
            raise ValueError(
                'Required property \'security_groups\' not present in SecurityGroupCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self,
                   'security_groups') and self.security_groups is not None:
            _dict['security_groups'] = [
                x.to_dict() for x in self.security_groups
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupCollectionFirst':
        """Initialize a SecurityGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupCollectionNext':
        """Initialize a SecurityGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentity():
    """
    Identifies a security group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupIdentityById', 'SecurityGroupIdentityByCRN',
                'SecurityGroupIdentityByHref'
            ]))
        raise Exception(msg)


class SecurityGroupReference():
    """
    SecurityGroupReference.

    :attr str id: The unique identifier for this security group.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str name: The user-defined name for this security group. Names must be
          unique within the VPC the security group resides in.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a SecurityGroupReference object.

        :param str id: The unique identifier for this security group.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str name: The user-defined name for this security group. Names must
               be unique within the VPC the security group resides in.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupReference':
        """Initialize a SecurityGroupReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in SecurityGroupReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRule():
    """
    SecurityGroupRule.

    :attr str id: The unique identifier for this security group rule.
    :attr str href: The URL for this security group rule.
    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRuleRemote remote: The IP addresses or security groups from
          which this rule allows traffic (or to which,
          for outbound rules). Can be specified as an IP address, a CIDR block, or a
          security
          group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to any
          source,
          for outbound rules).
    """

    def __init__(self,
                 id: str,
                 href: str,
                 direction: str,
                 remote: 'SecurityGroupRuleRemote',
                 *,
                 ip_version: str = None,
                 protocol: str = None) -> None:
        """
        Initialize a SecurityGroupRule object.

        :param str id: The unique identifier for this security group rule.
        :param str href: The URL for this security group rule.
        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param SecurityGroupRuleRemote remote: The IP addresses or security groups
               from which this rule allows traffic (or to which,
               for outbound rules). Can be specified as an IP address, a CIDR block, or a
               security
               group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to
               any source,
               for outbound rules).
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRuleSecurityGroupRuleProtocolAll',
                'SecurityGroupRuleSecurityGroupRuleProtocolICMP',
                'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRule':
        """Initialize a SecurityGroupRule object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = (
            "Cannot convert dictionary into an instance of base class 'SecurityGroupRule'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'SecurityGroupRuleSecurityGroupRuleProtocolAll',
            'SecurityGroupRuleSecurityGroupRuleProtocolICMP',
            'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a SecurityGroupRule object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['all'] = 'SecurityGroupRuleSecurityGroupRuleProtocolAll'
        mapping['icmp'] = 'SecurityGroupRuleSecurityGroupRuleProtocolICMP'
        mapping['tcp'] = 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP'
        mapping['udp'] = 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in SecurityGroupRule JSON'
            )
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRuleCollection():
    """
    Collection of rules in a security group.

    :attr List[SecurityGroupRule] rules: Array of rules.
    """

    def __init__(self, rules: List['SecurityGroupRule']) -> None:
        """
        Initialize a SecurityGroupRuleCollection object.

        :param List[SecurityGroupRule] rules: Array of rules.
        """
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleCollection':
        """Initialize a SecurityGroupRuleCollection object from a json dictionary."""
        args = {}
        if 'rules' in _dict:
            args['rules'] = [
                SecurityGroupRule.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in SecurityGroupRuleCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemote():
    """
    The IP addresses or security groups from which this rule will allow traffic (or to
    which, for outbound rules). Can be specified as an IP address, a CIDR block, or a
    security group. A CIDR block of `0.0.0.0/0` will allow traffic from any source (or to
    any source, for outbound rules).

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRulePatchRemote object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRulePatchRemoteIP',
                'SecurityGroupRulePatchRemoteCIDR',
                'SecurityGroupRulePatchRemoteSecurityGroupIdentity'
            ]))
        raise Exception(msg)


class SecurityGroupRulePrototype():
    """
    SecurityGroupRulePrototype.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses or
          security groups from which this rule will allow traffic (or to
          which, for outbound rules). Can be specified as an IP address, a CIDR block, or
          a
          security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to allow
          traffic
          from any source (or to any source, for outbound rules).
    """

    def __init__(self,
                 direction: str,
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 remote: 'SecurityGroupRulePrototypeRemote' = None) -> None:
        """
        Initialize a SecurityGroupRulePrototype object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        :param SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses
               or security groups from which this rule will allow traffic (or to
               which, for outbound rules). Can be specified as an IP address, a CIDR
               block, or a
               security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to
               allow traffic
               from any source (or to any source, for outbound rules).
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll',
                'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP',
                'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePrototype':
        """Initialize a SecurityGroupRulePrototype object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = (
            "Cannot convert dictionary into an instance of base class 'SecurityGroupRulePrototype'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll',
            'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP',
            'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a SecurityGroupRulePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping[
            'all'] = 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll'
        mapping[
            'icmp'] = 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP'
        mapping[
            'tcp'] = 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP'
        mapping[
            'udp'] = 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in SecurityGroupRulePrototype JSON'
            )
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRulePrototypeRemote():
    """
    The IP addresses or security groups from which this rule will allow traffic (or to
    which, for outbound rules). Can be specified as an IP address, a CIDR block, or a
    security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to allow traffic
    from any source (or to any source, for outbound rules).

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemote object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRulePrototypeRemoteIP',
                'SecurityGroupRulePrototypeRemoteCIDR',
                'SecurityGroupRulePrototypeRemoteSecurityGroupIdentity'
            ]))
        raise Exception(msg)


class SecurityGroupRuleRemote():
    """
    The IP addresses or security groups from which this rule allows traffic (or to which,
    for outbound rules). Can be specified as an IP address, a CIDR block, or a security
    group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to any source,
    for outbound rules).

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRuleRemote object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRuleRemoteIP', 'SecurityGroupRuleRemoteCIDR',
                'SecurityGroupRuleRemoteSecurityGroupReference'
            ]))
        raise Exception(msg)


class Subnet():
    """
    Subnet.

    :attr str id: The unique identifier for this subnet.
    :attr str crn: The CRN for this subnet.
    :attr str href: The URL for this subnet.
    :attr str name: The user-defined name for this subnet.
    :attr ResourceGroupReference resource_group: The resource group for this subnet.
    :attr int available_ipv4_address_count: The number of IPv4 addresses in this
          subnet that are not in-use, and have not been reserved by the user or the
          provider.
    :attr NetworkACLReference network_acl: The network ACL for this subnet.
    :attr int total_ipv4_address_count: The total number of IPv4 addresses in this
          subnet.
          Note: This is calculated as 2<sup>(32 − prefix length)</sup>. For example, the
          prefix length `/24` gives:<br> 2<sup>(32 − 24)</sup> = 2<sup>8</sup> = 256
          addresses.
    :attr datetime created_at: The date and time that the subnet was created.
    :attr str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
          format.
    :attr PublicGatewayReference public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr str status: The status of the subnet.
    :attr VPCReference vpc: The VPC this subnet is a part of.
    :attr ZoneReference zone: The zone this subnet resides in.
    :attr str ip_version: The IP version(s) supported by this subnet.
    """

    def __init__(self,
                 id: str,
                 crn: str,
                 href: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 available_ipv4_address_count: int,
                 network_acl: 'NetworkACLReference',
                 total_ipv4_address_count: int,
                 created_at: datetime,
                 ipv4_cidr_block: str,
                 status: str,
                 vpc: 'VPCReference',
                 zone: 'ZoneReference',
                 ip_version: str,
                 *,
                 public_gateway: 'PublicGatewayReference' = None) -> None:
        """
        Initialize a Subnet object.

        :param str id: The unique identifier for this subnet.
        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str name: The user-defined name for this subnet.
        :param ResourceGroupReference resource_group: The resource group for this
               subnet.
        :param int available_ipv4_address_count: The number of IPv4 addresses in
               this subnet that are not in-use, and have not been reserved by the user or
               the provider.
        :param NetworkACLReference network_acl: The network ACL for this subnet.
        :param int total_ipv4_address_count: The total number of IPv4 addresses in
               this subnet.
               Note: This is calculated as 2<sup>(32 − prefix length)</sup>. For example,
               the prefix length `/24` gives:<br> 2<sup>(32 − 24)</sup> = 2<sup>8</sup> =
               256 addresses.
        :param datetime created_at: The date and time that the subnet was created.
        :param str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
               format.
        :param str status: The status of the subnet.
        :param VPCReference vpc: The VPC this subnet is a part of.
        :param ZoneReference zone: The zone this subnet resides in.
        :param str ip_version: The IP version(s) supported by this subnet.
        :param PublicGatewayReference public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_group = resource_group
        self.available_ipv4_address_count = available_ipv4_address_count
        self.network_acl = network_acl
        self.total_ipv4_address_count = total_ipv4_address_count
        self.created_at = created_at
        self.ipv4_cidr_block = ipv4_cidr_block
        self.public_gateway = public_gateway
        self.status = status
        self.vpc = vpc
        self.zone = zone
        self.ip_version = ip_version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Subnet':
        """Initialize a Subnet object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Subnet JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Subnet JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Subnet JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Subnet JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in Subnet JSON'
            )
        if 'available_ipv4_address_count' in _dict:
            args['available_ipv4_address_count'] = _dict.get(
                'available_ipv4_address_count')
        else:
            raise ValueError(
                'Required property \'available_ipv4_address_count\' not present in Subnet JSON'
            )
        if 'network_acl' in _dict:
            args['network_acl'] = NetworkACLReference.from_dict(
                _dict.get('network_acl'))
        else:
            raise ValueError(
                'Required property \'network_acl\' not present in Subnet JSON')
        if 'total_ipv4_address_count' in _dict:
            args['total_ipv4_address_count'] = _dict.get(
                'total_ipv4_address_count')
        else:
            raise ValueError(
                'Required property \'total_ipv4_address_count\' not present in Subnet JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in Subnet JSON')
        if 'ipv4_cidr_block' in _dict:
            args['ipv4_cidr_block'] = _dict.get('ipv4_cidr_block')
        else:
            raise ValueError(
                'Required property \'ipv4_cidr_block\' not present in Subnet JSON'
            )
        if 'public_gateway' in _dict:
            args['public_gateway'] = PublicGatewayReference.from_dict(
                _dict.get('public_gateway'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Subnet JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in Subnet JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in Subnet JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in Subnet JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Subnet object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'available_ipv4_address_count'
                  ) and self.available_ipv4_address_count is not None:
            _dict[
                'available_ipv4_address_count'] = self.available_ipv4_address_count
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'total_ipv4_address_count'
                  ) and self.total_ipv4_address_count is not None:
            _dict['total_ipv4_address_count'] = self.total_ipv4_address_count
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self,
                   'ipv4_cidr_block') and self.ipv4_cidr_block is not None:
            _dict['ipv4_cidr_block'] = self.ipv4_cidr_block
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'vpc') and self.vpc is not None:
            _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Subnet object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Subnet') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Subnet') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the subnet.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) supported by this subnet.
        """
        IPV4 = 'ipv4'


class SubnetCollection():
    """
    SubnetCollection.

    :attr SubnetCollectionFirst first: A reference to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr SubnetCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[Subnet] subnets: Collection of subnets.
    """

    def __init__(self,
                 first: 'SubnetCollectionFirst',
                 limit: int,
                 total_count: int,
                 subnets: List['Subnet'],
                 *,
                 next: 'SubnetCollectionNext' = None) -> None:
        """
        Initialize a SubnetCollection object.

        :param SubnetCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[Subnet] subnets: Collection of subnets.
        :param SubnetCollectionNext next: (optional) A reference to the next page
               of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetCollection':
        """Initialize a SubnetCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SubnetCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in SubnetCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in SubnetCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = SubnetCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in SubnetCollection JSON'
            )
        if 'subnets' in _dict:
            args['subnets'] = [
                Subnet.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in SubnetCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'subnets') and self.subnets is not None:
            _dict['subnets'] = [x.to_dict() for x in self.subnets]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SubnetCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetCollectionFirst':
        """Initialize a SubnetCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SubnetCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SubnetCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetCollectionNext':
        """Initialize a SubnetCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SubnetCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetIdentity():
    """
    Identifies a subnet by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a SubnetIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SubnetIdentityById', 'SubnetIdentityByCRN',
                'SubnetIdentityByHref'
            ]))
        raise Exception(msg)


class SubnetPrototype():
    """
    SubnetPrototype.

    :attr str name: (optional) The user-defined name for this subnet. Names must be
          unique within the VPC the subnet resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr NetworkACLIdentity network_acl: (optional) The network ACL to use for this
          subnet.
    :attr PublicGatewayIdentity public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr VPCIdentity vpc: The VPC the subnet is to be a part of.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 ip_version: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a SubnetPrototype object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SubnetPrototypeSubnetByTotalCount',
                'SubnetPrototypeSubnetByCIDR'
            ]))
        raise Exception(msg)

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this subnet.
        """
        IPV4 = 'ipv4'


class SubnetReference():
    """
    SubnetReference.

    :attr str id: The unique identifier for this subnet.
    :attr str crn: The CRN for this subnet.
    :attr str href: The URL for this subnet.
    :attr str name: The user-defined name for this subnet.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a SubnetReference object.

        :param str id: The unique identifier for this subnet.
        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str name: The user-defined name for this subnet.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetReference':
        """Initialize a SubnetReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SubnetReference JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SubnetReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SubnetReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in SubnetReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPC():
    """
    VPC.

    :attr str id: The unique identifier for this VPC.
    :attr str crn: The CRN for this VPC.
    :attr str href: The URL for this VPC.
    :attr str name: The unique user-defined name for this VPC.
    :attr NetworkACLReference default_network_acl: The default network ACL to use
          for subnets created in this VPC.
    :attr bool classic_access: Indicates whether this VPC is connected to Classic
          Infrastructure. If true, this VPC's resources have private network connectivity
          to the account's Classic Infrastructure resources. Only one VPC, per region, may
          be connected in this way. This value is set at creation and subsequently
          immutable.
    :attr SecurityGroupReference default_security_group: The default security group
          to use for network interfaces created in this VPC.
    :attr ResourceGroupReference resource_group: The resource group for this VPC.
    :attr datetime created_at: The date and time that the VPC was created.
    :attr List[VPCCSESourceIP] cse_source_ips: (optional) Array of CSE ([Cloud
          Service
          Endpoint](https://cloud.ibm.com/docs/resources?topic=resources-service-endpoints))
          source IP addresses for the VPC. The VPC will have one CSE source IP address per
          zone.
    :attr str status: The status of this VPC.
    """

    def __init__(self,
                 id: str,
                 crn: str,
                 href: str,
                 name: str,
                 default_network_acl: 'NetworkACLReference',
                 classic_access: bool,
                 default_security_group: 'SecurityGroupReference',
                 resource_group: 'ResourceGroupReference',
                 created_at: datetime,
                 status: str,
                 *,
                 cse_source_ips: List['VPCCSESourceIP'] = None) -> None:
        """
        Initialize a VPC object.

        :param str id: The unique identifier for this VPC.
        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str name: The unique user-defined name for this VPC.
        :param NetworkACLReference default_network_acl: The default network ACL to
               use for subnets created in this VPC.
        :param bool classic_access: Indicates whether this VPC is connected to
               Classic Infrastructure. If true, this VPC's resources have private network
               connectivity to the account's Classic Infrastructure resources. Only one
               VPC, per region, may be connected in this way. This value is set at
               creation and subsequently immutable.
        :param SecurityGroupReference default_security_group: The default security
               group to use for network interfaces created in this VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               VPC.
        :param datetime created_at: The date and time that the VPC was created.
        :param str status: The status of this VPC.
        :param List[VPCCSESourceIP] cse_source_ips: (optional) Array of CSE ([Cloud
               Service
               Endpoint](https://cloud.ibm.com/docs/resources?topic=resources-service-endpoints))
               source IP addresses for the VPC. The VPC will have one CSE source IP
               address per zone.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.default_network_acl = default_network_acl
        self.classic_access = classic_access
        self.default_security_group = default_security_group
        self.resource_group = resource_group
        self.created_at = created_at
        self.cse_source_ips = cse_source_ips
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPC':
        """Initialize a VPC object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPC JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPC JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPC JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPC JSON')
        if 'default_network_acl' in _dict:
            args['default_network_acl'] = NetworkACLReference.from_dict(
                _dict.get('default_network_acl'))
        else:
            raise ValueError(
                'Required property \'default_network_acl\' not present in VPC JSON'
            )
        if 'classic_access' in _dict:
            args['classic_access'] = _dict.get('classic_access')
        else:
            raise ValueError(
                'Required property \'classic_access\' not present in VPC JSON')
        if 'default_security_group' in _dict:
            args['default_security_group'] = SecurityGroupReference.from_dict(
                _dict.get('default_security_group'))
        else:
            raise ValueError(
                'Required property \'default_security_group\' not present in VPC JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in VPC JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in VPC JSON')
        if 'cse_source_ips' in _dict:
            args['cse_source_ips'] = [
                VPCCSESourceIP.from_dict(x) for x in _dict.get('cse_source_ips')
            ]
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPC JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPC object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(
                self,
                'default_network_acl') and self.default_network_acl is not None:
            _dict['default_network_acl'] = self.default_network_acl.to_dict()
        if hasattr(self, 'classic_access') and self.classic_access is not None:
            _dict['classic_access'] = self.classic_access
        if hasattr(self, 'default_security_group'
                  ) and self.default_security_group is not None:
            _dict[
                'default_security_group'] = self.default_security_group.to_dict(
                )
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'cse_source_ips') and self.cse_source_ips is not None:
            _dict['cse_source_ips'] = [x.to_dict() for x in self.cse_source_ips]
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPC object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPC') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPC') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of this VPC.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


class VPCCSESourceIP():
    """
    VPCCSESourceIP.

    :attr IP ip: The Cloud Service Endpoint source IP address for this zone.
    :attr ZoneReference zone: The zone this Cloud Service Endpoint source IP belongs
          to.
    """

    def __init__(self, ip: 'IP', zone: 'ZoneReference') -> None:
        """
        Initialize a VPCCSESourceIP object.

        :param IP ip: The Cloud Service Endpoint source IP address for this zone.
        :param ZoneReference zone: The zone this Cloud Service Endpoint source IP
               belongs to.
        """
        self.ip = ip
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCCSESourceIP':
        """Initialize a VPCCSESourceIP object from a json dictionary."""
        args = {}
        if 'ip' in _dict:
            args['ip'] = IP.from_dict(_dict.get('ip'))
        else:
            raise ValueError(
                'Required property \'ip\' not present in VPCCSESourceIP JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in VPCCSESourceIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCCSESourceIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ip') and self.ip is not None:
            _dict['ip'] = self.ip.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCCSESourceIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCCSESourceIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCCSESourceIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCCollection():
    """
    VPCCollection.

    :attr VPCCollectionFirst first: A reference to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr VPCCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[VPC] vpcs: Collection of VPCs.
    """

    def __init__(self,
                 first: 'VPCCollectionFirst',
                 limit: int,
                 total_count: int,
                 vpcs: List['VPC'],
                 *,
                 next: 'VPCCollectionNext' = None) -> None:
        """
        Initialize a VPCCollection object.

        :param VPCCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[VPC] vpcs: Collection of VPCs.
        :param VPCCollectionNext next: (optional) A reference to the next page of
               resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.vpcs = vpcs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCCollection':
        """Initialize a VPCCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VPCCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in VPCCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in VPCCollection JSON')
        if 'next' in _dict:
            args['next'] = VPCCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in VPCCollection JSON'
            )
        if 'vpcs' in _dict:
            args['vpcs'] = [VPC.from_dict(x) for x in _dict.get('vpcs')]
        else:
            raise ValueError(
                'Required property \'vpcs\' not present in VPCCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'vpcs') and self.vpcs is not None:
            _dict['vpcs'] = [x.to_dict() for x in self.vpcs]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPCCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCCollectionFirst':
        """Initialize a VPCCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPCCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPCCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCCollectionNext':
        """Initialize a VPCCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPCCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCIdentity():
    """
    Identifies a VPC by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a VPCIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(
                ['VPCIdentityById', 'VPCIdentityByCRN', 'VPCIdentityByHref']))
        raise Exception(msg)


class VPCReference():
    """
    VPCReference.

    :attr str id: The unique identifier for this VPC.
    :attr str crn: The CRN for this VPC.
    :attr str href: The URL for this VPC.
    :attr str name: The unique user-defined name for this VPC.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a VPCReference object.

        :param str id: The unique identifier for this VPC.
        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str name: The unique user-defined name for this VPC.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReference':
        """Initialize a VPCReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPCReference JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPCReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPCReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPCReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGateway():
    """
    VPNGateway.

    :attr str id: The unique identifier for this VPN gateway.
    :attr str crn: The VPN gateway's CRN.
    :attr str href: The VPN gateway's canonical URL.
    :attr str name: The user-defined name for this VPN gateway.
    :attr str resource_type: The resource type.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr VPNGatewayPublicIp public_ip: The public IP address assigned to this VPN
          gateway.
    :attr List[VPNGatewayConnectionReference] connections: Collection of references
          to VPN gateway connections.
    :attr datetime created_at: The date and time that this VPN gateway was created.
    :attr str status: The status of the VPN gateway.
    :attr SubnetReference subnet:
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 resource_type: str, resource_group: 'ResourceGroupReference',
                 public_ip: 'VPNGatewayPublicIp',
                 connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, status: str,
                 subnet: 'SubnetReference') -> None:
        """
        Initialize a VPNGateway object.

        :param str id: The unique identifier for this VPN gateway.
        :param str crn: The VPN gateway's CRN.
        :param str href: The VPN gateway's canonical URL.
        :param str name: The user-defined name for this VPN gateway.
        :param str resource_type: The resource type.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param VPNGatewayPublicIp public_ip: The public IP address assigned to this
               VPN gateway.
        :param List[VPNGatewayConnectionReference] connections: Collection of
               references to VPN gateway connections.
        :param datetime created_at: The date and time that this VPN gateway was
               created.
        :param str status: The status of the VPN gateway.
        :param SubnetReference subnet:
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_type = resource_type
        self.resource_group = resource_group
        self.public_ip = public_ip
        self.connections = connections
        self.created_at = created_at
        self.status = status
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGateway':
        """Initialize a VPNGateway object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGateway JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPNGateway JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGateway JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGateway JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGateway JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in VPNGateway JSON'
            )
        if 'public_ip' in _dict:
            args['public_ip'] = VPNGatewayPublicIp.from_dict(
                _dict.get('public_ip'))
        else:
            raise ValueError(
                'Required property \'public_ip\' not present in VPNGateway JSON'
            )
        if 'connections' in _dict:
            args['connections'] = [
                VPNGatewayConnectionReference.from_dict(x)
                for x in _dict.get('connections')
            ]
        else:
            raise ValueError(
                'Required property \'connections\' not present in VPNGateway JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in VPNGateway JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGateway JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError(
                'Required property \'subnet\' not present in VPNGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGateway object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'public_ip') and self.public_ip is not None:
            _dict['public_ip'] = self.public_ip.to_dict()
        if hasattr(self, 'connections') and self.connections is not None:
            _dict['connections'] = [x.to_dict() for x in self.connections]
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'subnet') and self.subnet is not None:
            _dict['subnet'] = self.subnet.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGateway object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGateway') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGateway') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        VPN_GATEWAY = 'vpn_gateway'

    class StatusEnum(str, Enum):
        """
        The status of the VPN gateway.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


class VPNGatewayCollection():
    """
    VPNGatewayCollection.

    :attr VPNGatewayCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr VPNGatewayCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[VPNGateway] vpn_gateways: Collection of VPN gateways.
    """

    def __init__(self,
                 first: 'VPNGatewayCollectionFirst',
                 limit: int,
                 total_count: int,
                 vpn_gateways: List['VPNGateway'],
                 *,
                 next: 'VPNGatewayCollectionNext' = None) -> None:
        """
        Initialize a VPNGatewayCollection object.

        :param VPNGatewayCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[VPNGateway] vpn_gateways: Collection of VPN gateways.
        :param VPNGatewayCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.vpn_gateways = vpn_gateways

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayCollection':
        """Initialize a VPNGatewayCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VPNGatewayCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in VPNGatewayCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in VPNGatewayCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = VPNGatewayCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in VPNGatewayCollection JSON'
            )
        if 'vpn_gateways' in _dict:
            args['vpn_gateways'] = [
                VPNGateway.from_dict(x) for x in _dict.get('vpn_gateways')
            ]
        else:
            raise ValueError(
                'Required property \'vpn_gateways\' not present in VPNGatewayCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'vpn_gateways') and self.vpn_gateways is not None:
            _dict['vpn_gateways'] = [x.to_dict() for x in self.vpn_gateways]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPNGatewayCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayCollectionFirst':
        """Initialize a VPNGatewayCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPNGatewayCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayCollectionNext':
        """Initialize a VPNGatewayCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnection():
    """
    VPNGatewayConnection.

    :attr str id: The unique identifier for this VPN connection.
    :attr str href: The VPN connection's canonical URL.
    :attr str name: The user-defined name for this VPN gateway connection.
    :attr str resource_type: The resource type.
    :attr bool admin_state_up: If set to false, the VPN connection is shut down.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The preshared key.
    :attr List[str] local_cidrs: A collection of local CIDRs for this resource.
    :attr List[str] peer_cidrs: A collection of peer CIDRs for this resource.
    :attr str route_mode: The routing mode. Only `policy` is currently supported.
    :attr str authentication_mode: The authentication mode. Only `psk` is currently
          supported.
    :attr str status: The status of a VPN connection.
    :attr datetime created_at: The date and time that this VPN gateway connection
          was created.
    :attr VPNGatewayConnectionDPD dead_peer_detection: The Dead Peer Detection
          settings.
    :attr IKEPolicyReference ike_policy: (optional) Optional IKE policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr IPsecPolicyReference ipsec_policy: (optional) Optional IPsec policy
          configuration. The absence of a policy indicates
          autonegotiation.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 resource_type: str,
                 admin_state_up: bool,
                 peer_address: str,
                 psk: str,
                 local_cidrs: List[str],
                 peer_cidrs: List[str],
                 route_mode: str,
                 authentication_mode: str,
                 status: str,
                 created_at: datetime,
                 dead_peer_detection: 'VPNGatewayConnectionDPD',
                 *,
                 ike_policy: 'IKEPolicyReference' = None,
                 ipsec_policy: 'IPsecPolicyReference' = None) -> None:
        """
        Initialize a VPNGatewayConnection object.

        :param str id: The unique identifier for this VPN connection.
        :param str href: The VPN connection's canonical URL.
        :param str name: The user-defined name for this VPN gateway connection.
        :param str resource_type: The resource type.
        :param bool admin_state_up: If set to false, the VPN connection is shut
               down.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The preshared key.
        :param List[str] local_cidrs: A collection of local CIDRs for this
               resource.
        :param List[str] peer_cidrs: A collection of peer CIDRs for this resource.
        :param str route_mode: The routing mode. Only `policy` is currently
               supported.
        :param str authentication_mode: The authentication mode. Only `psk` is
               currently supported.
        :param str status: The status of a VPN connection.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection: The Dead Peer Detection
               settings.
        :param IKEPolicyReference ike_policy: (optional) Optional IKE policy
               configuration. The absence of a policy indicates autonegotiation.
        :param IPsecPolicyReference ipsec_policy: (optional) Optional IPsec policy
               configuration. The absence of a policy indicates
               autonegotiation.
        """
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type
        self.admin_state_up = admin_state_up
        self.peer_address = peer_address
        self.psk = psk
        self.local_cidrs = local_cidrs
        self.peer_cidrs = peer_cidrs
        self.route_mode = route_mode
        self.authentication_mode = authentication_mode
        self.status = status
        self.created_at = created_at
        self.dead_peer_detection = dead_peer_detection
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnection':
        """Initialize a VPNGatewayConnection object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGatewayConnection JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayConnection JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGatewayConnection JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGatewayConnection JSON'
            )
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        else:
            raise ValueError(
                'Required property \'admin_state_up\' not present in VPNGatewayConnection JSON'
            )
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError(
                'Required property \'peer_address\' not present in VPNGatewayConnection JSON'
            )
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError(
                'Required property \'psk\' not present in VPNGatewayConnection JSON'
            )
        if 'local_cidrs' in _dict:
            args['local_cidrs'] = _dict.get('local_cidrs')
        else:
            raise ValueError(
                'Required property \'local_cidrs\' not present in VPNGatewayConnection JSON'
            )
        if 'peer_cidrs' in _dict:
            args['peer_cidrs'] = _dict.get('peer_cidrs')
        else:
            raise ValueError(
                'Required property \'peer_cidrs\' not present in VPNGatewayConnection JSON'
            )
        if 'route_mode' in _dict:
            args['route_mode'] = _dict.get('route_mode')
        else:
            raise ValueError(
                'Required property \'route_mode\' not present in VPNGatewayConnection JSON'
            )
        if 'authentication_mode' in _dict:
            args['authentication_mode'] = _dict.get('authentication_mode')
        else:
            raise ValueError(
                'Required property \'authentication_mode\' not present in VPNGatewayConnection JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayConnection JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in VPNGatewayConnection JSON'
            )
        if 'dead_peer_detection' in _dict:
            args['dead_peer_detection'] = VPNGatewayConnectionDPD.from_dict(
                _dict.get('dead_peer_detection'))
        else:
            raise ValueError(
                'Required property \'dead_peer_detection\' not present in VPNGatewayConnection JSON'
            )
        if 'ike_policy' in _dict:
            args['ike_policy'] = IKEPolicyReference.from_dict(
                _dict.get('ike_policy'))
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = IPsecPolicyReference.from_dict(
                _dict.get('ipsec_policy'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'admin_state_up') and self.admin_state_up is not None:
            _dict['admin_state_up'] = self.admin_state_up
        if hasattr(self, 'peer_address') and self.peer_address is not None:
            _dict['peer_address'] = self.peer_address
        if hasattr(self, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        if hasattr(self, 'local_cidrs') and self.local_cidrs is not None:
            _dict['local_cidrs'] = self.local_cidrs
        if hasattr(self, 'peer_cidrs') and self.peer_cidrs is not None:
            _dict['peer_cidrs'] = self.peer_cidrs
        if hasattr(self, 'route_mode') and self.route_mode is not None:
            _dict['route_mode'] = self.route_mode
        if hasattr(
                self,
                'authentication_mode') and self.authentication_mode is not None:
            _dict['authentication_mode'] = self.authentication_mode
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(
                self,
                'dead_peer_detection') and self.dead_peer_detection is not None:
            _dict['dead_peer_detection'] = self.dead_peer_detection.to_dict()
        if hasattr(self, 'ike_policy') and self.ike_policy is not None:
            _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'

    class RouteModeEnum(str, Enum):
        """
        The routing mode. Only `policy` is currently supported.
        """
        POLICY = 'policy'

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode. Only `psk` is currently supported.
        """
        PSK = 'psk'

    class StatusEnum(str, Enum):
        """
        The status of a VPN connection.
        """
        DOWN = 'down'
        UP = 'up'


class VPNGatewayConnectionCollection():
    """
    Collection of VPN gateway connections in a VPN gateway.

    :attr List[VPNGatewayConnection] connections: Array of VPN gateway connections.
    """

    def __init__(self, connections: List['VPNGatewayConnection']) -> None:
        """
        Initialize a VPNGatewayConnectionCollection object.

        :param List[VPNGatewayConnection] connections: Array of VPN gateway
               connections.
        """
        self.connections = connections

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionCollection':
        """Initialize a VPNGatewayConnectionCollection object from a json dictionary."""
        args = {}
        if 'connections' in _dict:
            args['connections'] = [
                VPNGatewayConnection.from_dict(x)
                for x in _dict.get('connections')
            ]
        else:
            raise ValueError(
                'Required property \'connections\' not present in VPNGatewayConnectionCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'connections') and self.connections is not None:
            _dict['connections'] = [x.to_dict() for x in self.connections]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionDPD():
    """
    The Dead Peer Detection settings.

    :attr str action: Dead Peer Detection actions.
    :attr int interval: Dead Peer Detection interval in seconds.
    :attr int timeout: Dead Peer Detection timeout in seconds. Must be at least the
          interval.
    """

    def __init__(self, action: str, interval: int, timeout: int) -> None:
        """
        Initialize a VPNGatewayConnectionDPD object.

        :param str action: Dead Peer Detection actions.
        :param int interval: Dead Peer Detection interval in seconds.
        :param int timeout: Dead Peer Detection timeout in seconds. Must be at
               least the interval.
        """
        self.action = action
        self.interval = interval
        self.timeout = timeout

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionDPD':
        """Initialize a VPNGatewayConnectionDPD object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in VPNGatewayConnectionDPD JSON'
            )
        if 'interval' in _dict:
            args['interval'] = _dict.get('interval')
        else:
            raise ValueError(
                'Required property \'interval\' not present in VPNGatewayConnectionDPD JSON'
            )
        if 'timeout' in _dict:
            args['timeout'] = _dict.get('timeout')
        else:
            raise ValueError(
                'Required property \'timeout\' not present in VPNGatewayConnectionDPD JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionDPD object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'interval') and self.interval is not None:
            _dict['interval'] = self.interval
        if hasattr(self, 'timeout') and self.timeout is not None:
            _dict['timeout'] = self.timeout
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionDPD object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionDPD') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionDPD') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Dead Peer Detection actions.
        """
        CLEAR = 'clear'
        HOLD = 'hold'
        NONE = 'none'
        RESTART = 'restart'


class VPNGatewayConnectionDPDPrototype():
    """
    The Dead Peer Detection settings.

    :attr str action: (optional) Dead Peer Detection actions.
    :attr int interval: (optional) Dead Peer Detection interval in seconds.
    :attr int timeout: (optional) Dead Peer Detection timeout in seconds. Must be at
          least the interval.
    """

    def __init__(self,
                 *,
                 action: str = None,
                 interval: int = None,
                 timeout: int = None) -> None:
        """
        Initialize a VPNGatewayConnectionDPDPrototype object.

        :param str action: (optional) Dead Peer Detection actions.
        :param int interval: (optional) Dead Peer Detection interval in seconds.
        :param int timeout: (optional) Dead Peer Detection timeout in seconds. Must
               be at least the interval.
        """
        self.action = action
        self.interval = interval
        self.timeout = timeout

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionDPDPrototype':
        """Initialize a VPNGatewayConnectionDPDPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        if 'interval' in _dict:
            args['interval'] = _dict.get('interval')
        if 'timeout' in _dict:
            args['timeout'] = _dict.get('timeout')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionDPDPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'interval') and self.interval is not None:
            _dict['interval'] = self.interval
        if hasattr(self, 'timeout') and self.timeout is not None:
            _dict['timeout'] = self.timeout
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionDPDPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionDPDPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionDPDPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Dead Peer Detection actions.
        """
        CLEAR = 'clear'
        HOLD = 'hold'
        NONE = 'none'
        RESTART = 'restart'


class VPNGatewayConnectionLocalCIDRs():
    """
    VPNGatewayConnectionLocalCIDRs.

    :attr List[str] local_cidrs: (optional) A collection of local CIDRs for this
          resource.
    """

    def __init__(self, *, local_cidrs: List[str] = None) -> None:
        """
        Initialize a VPNGatewayConnectionLocalCIDRs object.

        :param List[str] local_cidrs: (optional) A collection of local CIDRs for
               this resource.
        """
        self.local_cidrs = local_cidrs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionLocalCIDRs':
        """Initialize a VPNGatewayConnectionLocalCIDRs object from a json dictionary."""
        args = {}
        if 'local_cidrs' in _dict:
            args['local_cidrs'] = _dict.get('local_cidrs')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionLocalCIDRs object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'local_cidrs') and self.local_cidrs is not None:
            _dict['local_cidrs'] = self.local_cidrs
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionLocalCIDRs object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionLocalCIDRs') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionLocalCIDRs') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPeerCIDRs():
    """
    VPNGatewayConnectionPeerCIDRs.

    :attr List[str] peer_cidrs: (optional) A collection of peer CIDRs for this
          resource.
    """

    def __init__(self, *, peer_cidrs: List[str] = None) -> None:
        """
        Initialize a VPNGatewayConnectionPeerCIDRs object.

        :param List[str] peer_cidrs: (optional) A collection of peer CIDRs for this
               resource.
        """
        self.peer_cidrs = peer_cidrs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPeerCIDRs':
        """Initialize a VPNGatewayConnectionPeerCIDRs object from a json dictionary."""
        args = {}
        if 'peer_cidrs' in _dict:
            args['peer_cidrs'] = _dict.get('peer_cidrs')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPeerCIDRs object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'peer_cidrs') and self.peer_cidrs is not None:
            _dict['peer_cidrs'] = self.peer_cidrs
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPeerCIDRs object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPeerCIDRs') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPeerCIDRs') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionReference():
    """
    VPNGatewayConnectionReference.

    :attr str id: The unique identifier for this VPN connection.
    :attr str href: The VPN connection's canonical URL.
    :attr str name: The user-defined name for this VPN connection.
    :attr str resource_type: The resource type.
    """

    def __init__(self, id: str, href: str, name: str,
                 resource_type: str) -> None:
        """
        Initialize a VPNGatewayConnectionReference object.

        :param str id: The unique identifier for this VPN connection.
        :param str href: The VPN connection's canonical URL.
        :param str name: The user-defined name for this VPN connection.
        :param str resource_type: The resource type.
        """
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionReference':
        """Initialize a VPNGatewayConnectionReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGatewayConnectionReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayConnectionReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGatewayConnectionReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGatewayConnectionReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'


class VPNGatewayPublicIp():
    """
    The public IP address assigned to this VPN gateway.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a VPNGatewayPublicIp object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayPublicIp':
        """Initialize a VPNGatewayPublicIp object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in VPNGatewayPublicIp JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPublicIp object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayPublicIp object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayPublicIp') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayPublicIp') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Volume():
    """
    Volume.

    :attr int iops: The bandwidth for the volume.
    :attr int capacity: The capacity of the volume in gigabytes. Note that the
          specified minimum and maximum capacity values for creating or updating volumes
          may expand in the future.
    :attr str id: The unique identifier for this volume.
    :attr str crn: The CRN for this volume.
    :attr str href: The URL for this volume.
    :attr str name: The unique user-defined name for this volume.
    :attr ResourceGroupReference resource_group: The resource group for this volume.
    :attr datetime created_at: The date and time that the volume was created.
    :attr str encryption: The type of encryption used on the volume.
    :attr EncryptionKeyReference encryption_key: (optional) A reference to the root
          key used to wrap the data encryption key for the volume.
          This property will be present for volumes with an `encryption` type of
          `user_managed`.
    :attr VolumeProfileReference profile: The profile this volume uses.
    :attr str status: The status of the volume.
    :attr List[VolumeAttachmentReferenceVolumeContext] volume_attachments: The
          collection of volume attachments attaching instances to the volume.
    :attr ZoneReference zone: The zone this volume resides in.
    """

    def __init__(
            self,
            iops: int,
            capacity: int,
            id: str,
            crn: str,
            href: str,
            name: str,
            resource_group: 'ResourceGroupReference',
            created_at: datetime,
            encryption: str,
            profile: 'VolumeProfileReference',
            status: str,
            volume_attachments: List['VolumeAttachmentReferenceVolumeContext'],
            zone: 'ZoneReference',
            *,
            encryption_key: 'EncryptionKeyReference' = None) -> None:
        """
        Initialize a Volume object.

        :param int iops: The bandwidth for the volume.
        :param int capacity: The capacity of the volume in gigabytes. Note that the
               specified minimum and maximum capacity values for creating or updating
               volumes may expand in the future.
        :param str id: The unique identifier for this volume.
        :param str crn: The CRN for this volume.
        :param str href: The URL for this volume.
        :param str name: The unique user-defined name for this volume.
        :param ResourceGroupReference resource_group: The resource group for this
               volume.
        :param datetime created_at: The date and time that the volume was created.
        :param str encryption: The type of encryption used on the volume.
        :param VolumeProfileReference profile: The profile this volume uses.
        :param str status: The status of the volume.
        :param List[VolumeAttachmentReferenceVolumeContext] volume_attachments: The
               collection of volume attachments attaching instances to the volume.
        :param ZoneReference zone: The zone this volume resides in.
        :param EncryptionKeyReference encryption_key: (optional) A reference to the
               root key used to wrap the data encryption key for the volume.
               This property will be present for volumes with an `encryption` type of
               `user_managed`.
        """
        self.iops = iops
        self.capacity = capacity
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_group = resource_group
        self.created_at = created_at
        self.encryption = encryption
        self.encryption_key = encryption_key
        self.profile = profile
        self.status = status
        self.volume_attachments = volume_attachments
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Volume':
        """Initialize a Volume object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        else:
            raise ValueError(
                'Required property \'iops\' not present in Volume JSON')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError(
                'Required property \'capacity\' not present in Volume JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Volume JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Volume JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Volume JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Volume JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in Volume JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in Volume JSON')
        if 'encryption' in _dict:
            args['encryption'] = _dict.get('encryption')
        else:
            raise ValueError(
                'Required property \'encryption\' not present in Volume JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = EncryptionKeyReference.from_dict(
                _dict.get('encryption_key'))
        if 'profile' in _dict:
            args['profile'] = VolumeProfileReference.from_dict(
                _dict.get('profile'))
        else:
            raise ValueError(
                'Required property \'profile\' not present in Volume JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Volume JSON')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentReferenceVolumeContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        else:
            raise ValueError(
                'Required property \'volume_attachments\' not present in Volume JSON'
            )
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in Volume JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Volume object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'encryption') and self.encryption is not None:
            _dict['encryption'] = self.encryption
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'zone') and self.zone is not None:
            _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Volume object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Volume') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Volume') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class EncryptionEnum(str, Enum):
        """
        The type of encryption used on the volume.
        """
        PROVIDER_MANAGED = 'provider_managed'
        USER_MANAGED = 'user_managed'

    class StatusEnum(str, Enum):
        """
        The status of the volume.
        """
        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'
        PENDING_DELETION = 'pending_deletion'


class VolumeAttachment():
    """
    VolumeAttachment.

    :attr str name: The user-defined name for this volume attachment.
    :attr bool delete_volume_on_instance_delete: (optional) If set to true, when
          deleting the instance the volume will also be deleted.
    :attr str id: The unique identifier for this volume attachment.
    :attr str href: The URL for this volume attachment.
    :attr VolumeAttachmentDevice device: (optional) Information about how the volume
          is exposed to the instance operating system.
          This property may be absent if the volume attachment's `status` is not
          `attached`.
    :attr VolumeReference volume: The attached volume.
    :attr datetime created_at: The date and time that the volume was attached.
    :attr str status: The status of this volume attachment.
    :attr str type: The type of volume attachment.
    """

    def __init__(self,
                 name: str,
                 id: str,
                 href: str,
                 volume: 'VolumeReference',
                 created_at: datetime,
                 status: str,
                 type: str,
                 *,
                 delete_volume_on_instance_delete: bool = None,
                 device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachment object.

        :param str name: The user-defined name for this volume attachment.
        :param str id: The unique identifier for this volume attachment.
        :param str href: The URL for this volume attachment.
        :param VolumeReference volume: The attached volume.
        :param datetime created_at: The date and time that the volume was attached.
        :param str status: The status of this volume attachment.
        :param str type: The type of volume attachment.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :param VolumeAttachmentDevice device: (optional) Information about how the
               volume is exposed to the instance operating system.
               This property may be absent if the volume attachment's `status` is not
               `attached`.
        """
        self.name = name
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.id = id
        self.href = href
        self.device = device
        self.volume = volume
        self.created_at = created_at
        self.status = status
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachment':
        """Initialize a VolumeAttachment object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeAttachment JSON'
            )
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachment JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachment JSON'
            )
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(
                _dict.get('device'))
        if 'volume' in _dict:
            args['volume'] = VolumeReference.from_dict(_dict.get('volume'))
        else:
            raise ValueError(
                'Required property \'volume\' not present in VolumeAttachment JSON'
            )
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in VolumeAttachment JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VolumeAttachment JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in VolumeAttachment JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachment object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'delete_volume_on_instance_delete'
                  ) and self.delete_volume_on_instance_delete is not None:
            _dict[
                'delete_volume_on_instance_delete'] = self.delete_volume_on_instance_delete
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'device') and self.device is not None:
            _dict['device'] = self.device.to_dict()
        if hasattr(self, 'volume') and self.volume is not None:
            _dict['volume'] = self.volume.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of this volume attachment.
        """
        ATTACHED = 'attached'
        ATTACHING = 'attaching'
        DETACHING = 'detaching'

    class TypeEnum(str, Enum):
        """
        The type of volume attachment.
        """
        BOOT = 'boot'
        DATA = 'data'


class VolumeAttachmentCollection():
    """
    VolumeAttachmentCollection.

    :attr List[VolumeAttachment] volume_attachments: Collection of volume
          attachments.
    """

    def __init__(self, volume_attachments: List['VolumeAttachment']) -> None:
        """
        Initialize a VolumeAttachmentCollection object.

        :param List[VolumeAttachment] volume_attachments: Collection of volume
               attachments.
        """
        self.volume_attachments = volume_attachments

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentCollection':
        """Initialize a VolumeAttachmentCollection object from a json dictionary."""
        args = {}
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachment.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        else:
            raise ValueError(
                'Required property \'volume_attachments\' not present in VolumeAttachmentCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentDevice():
    """
    VolumeAttachmentDevice.

    :attr str id: (optional) A unique identifier for the device which is exposed to
          the instance operating system.
    """

    def __init__(self, *, id: str = None) -> None:
        """
        Initialize a VolumeAttachmentDevice object.

        :param str id: (optional) A unique identifier for the device which is
               exposed to the instance operating system.
        """
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentDevice':
        """Initialize a VolumeAttachmentDevice object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentDevice object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentDevice object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentDevice') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentDevice') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceByImageContext():
    """
    VolumeAttachmentPrototypeInstanceByImageContext.

    :attr str name: (optional) The user-defined name for this volume attachment.
    :attr bool delete_volume_on_instance_delete: (optional) If set to true, when
          deleting the instance the volume will also be deleted.
    :attr VolumePrototypeInstanceByImageContext volume: The identity of the volume
          to attach to the instance, or a prototype object for a
          new volume.
    """

    def __init__(self,
                 volume: 'VolumePrototypeInstanceByImageContext',
                 *,
                 name: str = None,
                 delete_volume_on_instance_delete: bool = None) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceByImageContext object.

        :param VolumePrototypeInstanceByImageContext volume: The identity of the
               volume to attach to the instance, or a prototype object for a
               new volume.
        :param str name: (optional) The user-defined name for this volume
               attachment.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        """
        self.name = name
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.volume = volume

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'VolumeAttachmentPrototypeInstanceByImageContext':
        """Initialize a VolumeAttachmentPrototypeInstanceByImageContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'volume' in _dict:
            args['volume'] = VolumePrototypeInstanceByImageContext.from_dict(
                _dict.get('volume'))
        else:
            raise ValueError(
                'Required property \'volume\' not present in VolumeAttachmentPrototypeInstanceByImageContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceByImageContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'delete_volume_on_instance_delete'
                  ) and self.delete_volume_on_instance_delete is not None:
            _dict[
                'delete_volume_on_instance_delete'] = self.delete_volume_on_instance_delete
        if hasattr(self, 'volume') and self.volume is not None:
            _dict['volume'] = self.volume.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeInstanceByImageContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'VolumeAttachmentPrototypeInstanceByImageContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'VolumeAttachmentPrototypeInstanceByImageContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContext():
    """
    VolumeAttachmentPrototypeInstanceContext.

    :attr str name: (optional) The user-defined name for this volume attachment.
    :attr bool delete_volume_on_instance_delete: (optional) If set to true, when
          deleting the instance the volume will also be deleted.
    :attr VolumeAttachmentPrototypeInstanceContextVolume volume: The identity of the
          volume to attach to the instance, or a prototype object for a new
          volume.
    """

    def __init__(self,
                 volume: 'VolumeAttachmentPrototypeInstanceContextVolume',
                 *,
                 name: str = None,
                 delete_volume_on_instance_delete: bool = None) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContext object.

        :param VolumeAttachmentPrototypeInstanceContextVolume volume: The identity
               of the volume to attach to the instance, or a prototype object for a new
               volume.
        :param str name: (optional) The user-defined name for this volume
               attachment.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        """
        self.name = name
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.volume = volume

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'VolumeAttachmentPrototypeInstanceContext':
        """Initialize a VolumeAttachmentPrototypeInstanceContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'volume' in _dict:
            args['volume'] = _dict.get('volume')
        else:
            raise ValueError(
                'Required property \'volume\' not present in VolumeAttachmentPrototypeInstanceContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'delete_volume_on_instance_delete'
                  ) and self.delete_volume_on_instance_delete is not None:
            _dict[
                'delete_volume_on_instance_delete'] = self.delete_volume_on_instance_delete
        if hasattr(self, 'volume') and self.volume is not None:
            if isinstance(self.volume, dict):
                _dict['volume'] = self.volume
            else:
                _dict['volume'] = self.volume.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeInstanceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeInstanceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeInstanceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContextVolume():
    """
    The identity of the volume to attach to the instance, or a prototype object for a new
    volume.

    """

    def __init__(self) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolume object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentity',
                'VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContext'
            ]))
        raise Exception(msg)


class VolumeAttachmentReferenceInstanceContext():
    """
    VolumeAttachmentReferenceInstanceContext.

    :attr str id: The unique identifier for this volume attachment.
    :attr str href: The URL for this volume attachment.
    :attr str name: The user-defined name for this volume attachment.
    :attr VolumeAttachmentDevice device: (optional) Information about how the volume
          is exposed to the instance operating system.
          This property may be absent if the volume attachment's `status` is not
          `attached`.
    :attr VolumeReference volume: The attached volume.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 volume: 'VolumeReference',
                 *,
                 device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachmentReferenceInstanceContext object.

        :param str id: The unique identifier for this volume attachment.
        :param str href: The URL for this volume attachment.
        :param str name: The user-defined name for this volume attachment.
        :param VolumeReference volume: The attached volume.
        :param VolumeAttachmentDevice device: (optional) Information about how the
               volume is exposed to the instance operating system.
               This property may be absent if the volume attachment's `status` is not
               `attached`.
        """
        self.id = id
        self.href = href
        self.name = name
        self.device = device
        self.volume = volume

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'VolumeAttachmentReferenceInstanceContext':
        """Initialize a VolumeAttachmentReferenceInstanceContext object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachmentReferenceInstanceContext JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachmentReferenceInstanceContext JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeAttachmentReferenceInstanceContext JSON'
            )
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(
                _dict.get('device'))
        if 'volume' in _dict:
            args['volume'] = VolumeReference.from_dict(_dict.get('volume'))
        else:
            raise ValueError(
                'Required property \'volume\' not present in VolumeAttachmentReferenceInstanceContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceInstanceContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'device') and self.device is not None:
            _dict['device'] = self.device.to_dict()
        if hasattr(self, 'volume') and self.volume is not None:
            _dict['volume'] = self.volume.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceInstanceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentReferenceInstanceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentReferenceInstanceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentReferenceVolumeContext():
    """
    VolumeAttachmentReferenceVolumeContext.

    :attr str id: The unique identifier for this volume attachment.
    :attr str href: The URL for this volume attachment.
    :attr str name: The user-defined name for this volume attachment.
    :attr bool delete_volume_on_instance_delete: If set to true, when deleting the
          instance the volume will also be deleted.
    :attr VolumeAttachmentDevice device: (optional) Information about how the volume
          is exposed to the instance operating system.
          This property may be absent if the volume attachment's `status` is not
          `attached`.
    :attr InstanceReference instance: The attached instance.
    :attr str type: The type of volume attachment.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 delete_volume_on_instance_delete: bool,
                 instance: 'InstanceReference',
                 type: str,
                 *,
                 device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachmentReferenceVolumeContext object.

        :param str id: The unique identifier for this volume attachment.
        :param str href: The URL for this volume attachment.
        :param str name: The user-defined name for this volume attachment.
        :param bool delete_volume_on_instance_delete: If set to true, when deleting
               the instance the volume will also be deleted.
        :param InstanceReference instance: The attached instance.
        :param str type: The type of volume attachment.
        :param VolumeAttachmentDevice device: (optional) Information about how the
               volume is exposed to the instance operating system.
               This property may be absent if the volume attachment's `status` is not
               `attached`.
        """
        self.id = id
        self.href = href
        self.name = name
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.device = device
        self.instance = instance
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentReferenceVolumeContext':
        """Initialize a VolumeAttachmentReferenceVolumeContext object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        else:
            raise ValueError(
                'Required property \'delete_volume_on_instance_delete\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(
                _dict.get('device'))
        if 'instance' in _dict:
            args['instance'] = InstanceReference.from_dict(
                _dict.get('instance'))
        else:
            raise ValueError(
                'Required property \'instance\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceVolumeContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'delete_volume_on_instance_delete'
                  ) and self.delete_volume_on_instance_delete is not None:
            _dict[
                'delete_volume_on_instance_delete'] = self.delete_volume_on_instance_delete
        if hasattr(self, 'device') and self.device is not None:
            _dict['device'] = self.device.to_dict()
        if hasattr(self, 'instance') and self.instance is not None:
            _dict['instance'] = self.instance.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceVolumeContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentReferenceVolumeContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentReferenceVolumeContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of volume attachment.
        """
        BOOT = 'boot'
        DATA = 'data'


class VolumeCollection():
    """
    VolumeCollection.

    :attr VolumeCollectionFirst first: A reference to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr VolumeCollectionNext next: (optional) A reference to the next page of
          resources; this reference is included for all pages
          except the last page.
    :attr List[Volume] volumes: Collection of volumes.
    """

    def __init__(self,
                 first: 'VolumeCollectionFirst',
                 limit: int,
                 volumes: List['Volume'],
                 *,
                 next: 'VolumeCollectionNext' = None) -> None:
        """
        Initialize a VolumeCollection object.

        :param VolumeCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[Volume] volumes: Collection of volumes.
        :param VolumeCollectionNext next: (optional) A reference to the next page
               of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.volumes = volumes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeCollection':
        """Initialize a VolumeCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VolumeCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in VolumeCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in VolumeCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = VolumeCollectionNext.from_dict(_dict.get('next'))
        if 'volumes' in _dict:
            args['volumes'] = [
                Volume.from_dict(x) for x in _dict.get('volumes')
            ]
        else:
            raise ValueError(
                'Required property \'volumes\' not present in VolumeCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'volumes') and self.volumes is not None:
            _dict['volumes'] = [x.to_dict() for x in self.volumes]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeCollectionFirst':
        """Initialize a VolumeCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeCollectionNext':
        """Initialize a VolumeCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeIdentity():
    """
    Identifies a volume by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a VolumeIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeIdentityById', 'VolumeIdentityByCRN',
                'VolumeIdentityByHref'
            ]))
        raise Exception(msg)


class VolumeProfile():
    """
    VolumeProfile.

    :attr str name: The name for this volume profile.
    :attr str href: The URL for this volume profile.
    :attr str family: (optional) The product family this volume profile belongs to.
    """

    def __init__(self, name: str, href: str, *, family: str = None) -> None:
        """
        Initialize a VolumeProfile object.

        :param str name: The name for this volume profile.
        :param str href: The URL for this volume profile.
        :param str family: (optional) The product family this volume profile
               belongs to.
        """
        self.name = name
        self.href = href
        self.family = family

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfile':
        """Initialize a VolumeProfile object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeProfile JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfile JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileCollection():
    """
    VolumeProfileCollection.

    :attr VolumeProfileCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr VolumeProfileCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[VolumeProfile] profiles: Collection of volume profiles.
    """

    def __init__(self,
                 first: 'VolumeProfileCollectionFirst',
                 limit: int,
                 total_count: int,
                 profiles: List['VolumeProfile'],
                 *,
                 next: 'VolumeProfileCollectionNext' = None) -> None:
        """
        Initialize a VolumeProfileCollection object.

        :param VolumeProfileCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[VolumeProfile] profiles: Collection of volume profiles.
        :param VolumeProfileCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.profiles = profiles

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileCollection':
        """Initialize a VolumeProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VolumeProfileCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in VolumeProfileCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in VolumeProfileCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = VolumeProfileCollectionNext.from_dict(
                _dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in VolumeProfileCollection JSON'
            )
        if 'profiles' in _dict:
            args['profiles'] = [
                VolumeProfile.from_dict(x) for x in _dict.get('profiles')
            ]
        else:
            raise ValueError(
                'Required property \'profiles\' not present in VolumeProfileCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'profiles') and self.profiles is not None:
            _dict['profiles'] = [x.to_dict() for x in self.profiles]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileCollectionFirst():
    """
    A reference to the first page of resources.

    :attr str href: The URL for the first page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeProfileCollectionFirst object.

        :param str href: The URL for the first page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileCollectionFirst':
        """Initialize a VolumeProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfileCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeProfileCollectionNext object.

        :param str href: The URL for the next page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileCollectionNext':
        """Initialize a VolumeProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfileCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileIdentity():
    """
    Identifies a volume profile by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a VolumeProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(
                ['VolumeProfileIdentityByName', 'VolumeProfileIdentityByHref']))
        raise Exception(msg)


class VolumeProfileReference():
    """
    VolumeProfileReference.

    :attr str name: The name for this volume profile.
    :attr str href: The URL for this volume profile.
    """

    def __init__(self, name: str, href: str) -> None:
        """
        Initialize a VolumeProfileReference object.

        :param str name: The name for this volume profile.
        :param str href: The URL for this volume profile.
        """
        self.name = name
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileReference':
        """Initialize a VolumeProfileReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeProfileReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfileReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumePrototype():
    """
    VolumePrototype.

    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr ZoneIdentity zone: The location of the volume.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 zone: 'ZoneIdentity',
                 *,
                 name: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a VolumePrototype object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param ZoneIdentity zone: The location of the volume.
        :param str name: (optional) The unique user-defined name for this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VolumePrototypeVolumeByCapacity']))
        raise Exception(msg)


class VolumePrototypeInstanceByImageContext():
    """
    VolumePrototypeInstanceByImageContext.

    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int capacity: (optional) The capacity of the volume in gigabytes. Note
          that the specified minimum and maximum capacity values for creating or updating
          volumes may expand in the future.
    :attr int iops: (optional) The bandwidth for the volume.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 *,
                 name: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 capacity: int = None,
                 iops: int = None) -> None:
        """
        Initialize a VolumePrototypeInstanceByImageContext object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param str name: (optional) The unique user-defined name for this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int capacity: (optional) The capacity of the volume in gigabytes.
               Note that the specified minimum and maximum capacity values for creating or
               updating volumes may expand in the future.
        :param int iops: (optional) The bandwidth for the volume.
        """
        self.name = name
        self.profile = profile
        self.encryption_key = encryption_key
        self.capacity = capacity
        self.iops = iops

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeInstanceByImageContext':
        """Initialize a VolumePrototypeInstanceByImageContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError(
                'Required property \'profile\' not present in VolumePrototypeInstanceByImageContext JSON'
            )
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumePrototypeInstanceByImageContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumePrototypeInstanceByImageContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumePrototypeInstanceByImageContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumePrototypeInstanceByImageContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeReference():
    """
    VolumeReference.

    :attr str id: The unique identifier for this volume.
    :attr str crn: The CRN for this volume.
    :attr str href: The URL for this volume.
    :attr str name: The unique user-defined name for this volume.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a VolumeReference object.

        :param str id: The unique identifier for this volume.
        :param str crn: The CRN for this volume.
        :param str href: The URL for this volume.
        :param str name: The unique user-defined name for this volume.
        """
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReference':
        """Initialize a VolumeReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeReference JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VolumeReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Zone():
    """
    Zone.

    :attr str name: The name for this zone.
    :attr str href: The URL for this zone.
    :attr RegionReference region: The region this zone belongs to.
    :attr str status: The availability status of this zone.
    """

    def __init__(self, name: str, href: str, region: 'RegionReference',
                 status: str) -> None:
        """
        Initialize a Zone object.

        :param str name: The name for this zone.
        :param str href: The URL for this zone.
        :param RegionReference region: The region this zone belongs to.
        :param str status: The availability status of this zone.
        """
        self.name = name
        self.href = href
        self.region = region
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Zone':
        """Initialize a Zone object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Zone JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Zone JSON')
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        else:
            raise ValueError(
                'Required property \'region\' not present in Zone JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Zone JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Zone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'region') and self.region is not None:
            _dict['region'] = self.region.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Zone object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Zone') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Zone') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The availability status of this zone.
        """
        AVAILABLE = 'available'
        IMPAIRED = 'impaired'
        UNAVAILABLE = 'unavailable'


class ZoneCollection():
    """
    ZoneCollection.

    :attr List[Zone] zones: Collection of zones.
    """

    def __init__(self, zones: List['Zone']) -> None:
        """
        Initialize a ZoneCollection object.

        :param List[Zone] zones: Collection of zones.
        """
        self.zones = zones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ZoneCollection':
        """Initialize a ZoneCollection object from a json dictionary."""
        args = {}
        if 'zones' in _dict:
            args['zones'] = [Zone.from_dict(x) for x in _dict.get('zones')]
        else:
            raise ValueError(
                'Required property \'zones\' not present in ZoneCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ZoneCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'zones') and self.zones is not None:
            _dict['zones'] = [x.to_dict() for x in self.zones]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ZoneCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ZoneCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ZoneCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ZoneIdentity():
    """
    Identifies a zone by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a ZoneIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ZoneIdentityByName', 'ZoneIdentityByHref']))
        raise Exception(msg)


class ZoneReference():
    """
    ZoneReference.

    :attr str name: The name for this zone.
    :attr str href: The URL for this zone.
    """

    def __init__(self, name: str, href: str) -> None:
        """
        Initialize a ZoneReference object.

        :param str name: The name for this zone.
        :param str href: The URL for this zone.
        """
        self.name = name
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ZoneReference':
        """Initialize a ZoneReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ZoneReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ZoneReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ZoneReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ZoneReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ZoneReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ZoneReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CertificateInstanceIdentityByCRN(CertificateInstanceIdentity):
    """
    CertificateInstanceIdentityByCRN.

    :attr str crn: The CRN for this certificate instance.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a CertificateInstanceIdentityByCRN object.

        :param str crn: The CRN for this certificate instance.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CertificateInstanceIdentityByCRN':
        """Initialize a CertificateInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in CertificateInstanceIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CertificateInstanceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CertificateInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CertificateInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CertificateInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CloudObjectStorageBucketIdentityByName(CloudObjectStorageBucketIdentity):
    """
    CloudObjectStorageBucketIdentityByName.

    :attr str name: The globally unique name of this COS bucket.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a CloudObjectStorageBucketIdentityByName object.

        :param str name: The globally unique name of this COS bucket.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CloudObjectStorageBucketIdentityByName':
        """Initialize a CloudObjectStorageBucketIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in CloudObjectStorageBucketIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CloudObjectStorageBucketIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CloudObjectStorageBucketIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CloudObjectStorageBucketIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CloudObjectStorageBucketIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EncryptionKeyIdentityByCRN(EncryptionKeyIdentity):
    """
    EncryptionKeyIdentityByCRN.

    :attr str crn: The CRN of the [Key Protect Root
          Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial)
          or [Hyper Protect Crypto Service Root
          Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for this
          resource.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a EncryptionKeyIdentityByCRN object.

        :param str crn: The CRN of the [Key Protect Root
               Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial)
               or [Hyper Protect Crypto Service Root
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for
               this resource.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EncryptionKeyIdentityByCRN':
        """Initialize a EncryptionKeyIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in EncryptionKeyIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EncryptionKeyIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EncryptionKeyIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EncryptionKeyIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EncryptionKeyIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPByTargetTargetNetworkInterfaceIdentityByHref(
        FloatingIPByTargetTarget):
    """
    FloatingIPByTargetTargetNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this network interface.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPByTargetTargetNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FloatingIPByTargetTargetNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPByTargetTargetNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPByTargetTargetNetworkInterfaceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPByTargetTargetNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPByTargetTargetNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'FloatingIPByTargetTargetNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'FloatingIPByTargetTargetNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPByTargetTargetNetworkInterfaceIdentityById(
        FloatingIPByTargetTarget):
    """
    FloatingIPByTargetTargetNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this network interface.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FloatingIPByTargetTargetNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'FloatingIPByTargetTargetNetworkInterfaceIdentityById':
        """Initialize a FloatingIPByTargetTargetNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIPByTargetTargetNetworkInterfaceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPByTargetTargetNetworkInterfaceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPByTargetTargetNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'FloatingIPByTargetTargetNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'FloatingIPByTargetTargetNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(
        FloatingIPPatchTargetNetworkInterfaceIdentity):
    """
    FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this network interface.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById(
        FloatingIPPatchTargetNetworkInterfaceIdentity):
    """
    FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this network interface.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FloatingIPPatchTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPrototypeFloatingIPByTarget(FloatingIPPrototype):
    """
    FloatingIPPrototypeFloatingIPByTarget.

    :attr str name: (optional) The unique user-defined name for this floating IP. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr FloatingIPByTargetTarget target: The network interface this floating IP is
          to be bound to.
    """

    def __init__(self,
                 target: 'FloatingIPByTargetTarget',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByTarget object.

        :param FloatingIPByTargetTarget target: The network interface this floating
               IP is to be bound to.
        :param str name: (optional) The unique user-defined name for this floating
               IP. If unspecified, the name will be a hyphenated list of randomly-selected
               words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPPrototypeFloatingIPByTarget':
        """Initialize a FloatingIPPrototypeFloatingIPByTarget object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError(
                'Required property \'target\' not present in FloatingIPPrototypeFloatingIPByTarget JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPrototypeFloatingIPByTarget object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPPrototypeFloatingIPByTarget object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPPrototypeFloatingIPByTarget') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPPrototypeFloatingIPByTarget') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPrototypeFloatingIPByZone(FloatingIPPrototype):
    """
    FloatingIPPrototypeFloatingIPByZone.

    :attr str name: (optional) The unique user-defined name for this floating IP. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr ZoneIdentity zone: The identity of the zone to provision a floating IP in.
    """

    def __init__(self,
                 zone: 'ZoneIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByZone object.

        :param ZoneIdentity zone: The identity of the zone to provision a floating
               IP in.
        :param str name: (optional) The unique user-defined name for this floating
               IP. If unspecified, the name will be a hyphenated list of randomly-selected
               words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPPrototypeFloatingIPByZone':
        """Initialize a FloatingIPPrototypeFloatingIPByZone object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in FloatingIPPrototypeFloatingIPByZone JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPrototypeFloatingIPByZone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPPrototypeFloatingIPByZone object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPPrototypeFloatingIPByZone') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPPrototypeFloatingIPByZone') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetNetworkInterfaceReference(FloatingIPTarget):
    """
    FloatingIPTargetNetworkInterfaceReference.

    :attr str name: The user-defined name for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str href: The URL for this network interface.
    :attr str primary_ipv4_address: The primary IPv4 address.
    :attr str resource_type: The resource type.
    """

    def __init__(self, name: str, id: str, href: str, primary_ipv4_address: str,
                 resource_type: str) -> None:
        """
        Initialize a FloatingIPTargetNetworkInterfaceReference object.

        :param str name: The user-defined name for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str href: The URL for this network interface.
        :param str primary_ipv4_address: The primary IPv4 address.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.id = id
        self.href = href
        self.primary_ipv4_address = primary_ipv4_address
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'FloatingIPTargetNetworkInterfaceReference':
        """Initialize a FloatingIPTargetNetworkInterfaceReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FloatingIPTargetNetworkInterfaceReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIPTargetNetworkInterfaceReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPTargetNetworkInterfaceReference JSON'
            )
        if 'primary_ipv4_address' in _dict:
            args['primary_ipv4_address'] = _dict.get('primary_ipv4_address')
        else:
            raise ValueError(
                'Required property \'primary_ipv4_address\' not present in FloatingIPTargetNetworkInterfaceReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in FloatingIPTargetNetworkInterfaceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetNetworkInterfaceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'primary_ipv4_address'
                  ) and self.primary_ipv4_address is not None:
            _dict['primary_ipv4_address'] = self.primary_ipv4_address
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPTargetNetworkInterfaceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'FloatingIPTargetNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'FloatingIPTargetNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        NETWORK_INTERFACE = 'network_interface'


class FloatingIPTargetPublicGatewayReference(FloatingIPTarget):
    """
    FloatingIPTargetPublicGatewayReference.

    :attr str id: The unique identifier for this public gateway.
    :attr str crn: The CRN for this public gateway.
    :attr str href: The URL for this public gateway.
    :attr str name: The user-defined name for this public gateway.
    :attr str resource_type: The resource type.
    """

    def __init__(self, id: str, crn: str, href: str, name: str,
                 resource_type: str) -> None:
        """
        Initialize a FloatingIPTargetPublicGatewayReference object.

        :param str id: The unique identifier for this public gateway.
        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str name: The user-defined name for this public gateway.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPublicGatewayReference':
        """Initialize a FloatingIPTargetPublicGatewayReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPublicGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPTargetPublicGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPublicGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPublicGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        PUBLIC_GATEWAY = 'public_gateway'


class FlowLogCollectorPrototypeTargetInstanceIdentity(
        FlowLogCollectorPrototypeTarget):
    """
    Identifies a virtual server instance by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetInstanceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById',
                'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN',
                'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorPrototypeTargetNetworkInterfaceIdentity(
        FlowLogCollectorPrototypeTarget):
    """
    Identifies a network interface by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById',
                'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorPrototypeTargetSubnetIdentity(
        FlowLogCollectorPrototypeTarget):
    """
    Identifies a subnet by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetSubnetIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById',
                'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN',
                'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorPrototypeTargetVPCIdentity(FlowLogCollectorPrototypeTarget
                                                ):
    """
    Identifies a VPC by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetVPCIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById',
                'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN',
                'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorTargetInstanceReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetInstanceReference.

    :attr str id: The unique identifier for this virtual server instance.
    :attr str crn: The CRN for this virtual server instance.
    :attr str href: The URL for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a FlowLogCollectorTargetInstanceReference object.

        :param str id: The unique identifier for this virtual server instance.
        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'FlowLogCollectorTargetInstanceReference':
        """Initialize a FlowLogCollectorTargetInstanceReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetInstanceReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetInstanceReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetInstanceReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FlowLogCollectorTargetInstanceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetInstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext(
        FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext.

    :attr str id: The unique identifier for this network interface.
    :attr str href: The URL for this network interface.
    :attr str name: The user-defined name for this network interface.
    :attr str resource_type: The resource type.
    """

    def __init__(self, id: str, href: str, name: str,
                 resource_type: str) -> None:
        """
        Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object.

        :param str id: The unique identifier for this network interface.
        :param str href: The URL for this network interface.
        :param str name: The user-defined name for this network interface.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext':
        """Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        NETWORK_INTERFACE = 'network_interface'


class FlowLogCollectorTargetSubnetReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetSubnetReference.

    :attr str id: The unique identifier for this subnet.
    :attr str crn: The CRN for this subnet.
    :attr str href: The URL for this subnet.
    :attr str name: The user-defined name for this subnet.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a FlowLogCollectorTargetSubnetReference object.

        :param str id: The unique identifier for this subnet.
        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str name: The user-defined name for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetSubnetReference':
        """Initialize a FlowLogCollectorTargetSubnetReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetSubnetReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetSubnetReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetSubnetReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FlowLogCollectorTargetSubnetReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetSubnetReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetSubnetReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetSubnetReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetSubnetReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetVPCReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetVPCReference.

    :attr str id: The unique identifier for this VPC.
    :attr str crn: The CRN for this VPC.
    :attr str href: The URL for this VPC.
    :attr str name: The unique user-defined name for this VPC.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a FlowLogCollectorTargetVPCReference object.

        :param str id: The unique identifier for this VPC.
        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str name: The unique user-defined name for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetVPCReference':
        """Initialize a FlowLogCollectorTargetVPCReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetVPCReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetVPCReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetVPCReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in FlowLogCollectorTargetVPCReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetVPCReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetVPCReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetVPCReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetVPCReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IKEPolicyIdentityByHref(IKEPolicyIdentity):
    """
    IKEPolicyIdentityByHref.

    :attr str href: The IKE policy's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IKEPolicyIdentityByHref object.

        :param str href: The IKE policy's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyIdentityByHref':
        """Initialize a IKEPolicyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicyIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IKEPolicyIdentityById(IKEPolicyIdentity):
    """
    IKEPolicyIdentityById.

    :attr str id: The unique identifier for this IKE policy.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a IKEPolicyIdentityById object.

        :param str id: The unique identifier for this IKE policy.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyIdentityById':
        """Initialize a IKEPolicyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in IKEPolicyIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicyIdentityByHref(IPsecPolicyIdentity):
    """
    IPsecPolicyIdentityByHref.

    :attr str href: The IPsec policy's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IPsecPolicyIdentityByHref object.

        :param str href: The IPsec policy's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyIdentityByHref':
        """Initialize a IPsecPolicyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IPsecPolicyIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicyIdentityById(IPsecPolicyIdentity):
    """
    IPsecPolicyIdentityById.

    :attr str id: The unique identifier for this IPsec policy.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a IPsecPolicyIdentityById object.

        :param str id: The unique identifier for this IPsec policy.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyIdentityById':
        """Initialize a IPsecPolicyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in IPsecPolicyIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageIdentityByCRN(ImageIdentity):
    """
    ImageIdentityByCRN.

    :attr str crn: The CRN for this image.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a ImageIdentityByCRN object.

        :param str crn: The CRN for this image.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageIdentityByCRN':
        """Initialize a ImageIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in ImageIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageIdentityByHref(ImageIdentity):
    """
    ImageIdentityByHref.

    :attr str href: The URL for this image.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ImageIdentityByHref object.

        :param str href: The URL for this image.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageIdentityByHref':
        """Initialize a ImageIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ImageIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageIdentityById(ImageIdentity):
    """
    ImageIdentityById.

    :attr str id: The unique identifier for this image.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a ImageIdentityById object.

        :param str id: The unique identifier for this image.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageIdentityById':
        """Initialize a ImageIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ImageIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImagePrototypeImageByFile(ImagePrototype):
    """
    ImagePrototypeImageByFile.

    :attr str name: (optional) The unique user-defined name for this image. Names
          starting with "ibm-" are not allowed. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr ImageFilePrototype file: The file from which to create the image.
    :attr OperatingSystemIdentity operating_system: The identity of the [supported
          operating
          system](https://cloud.ibm.com/apidocs/vpc#retrieves-all-operating-systems)
          included in
          this image.
    """

    def __init__(self,
                 file: 'ImageFilePrototype',
                 operating_system: 'OperatingSystemIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a ImagePrototypeImageByFile object.

        :param ImageFilePrototype file: The file from which to create the image.
        :param OperatingSystemIdentity operating_system: The identity of the
               [supported operating
               system](https://cloud.ibm.com/apidocs/vpc#retrieves-all-operating-systems)
               included in
               this image.
        :param str name: (optional) The unique user-defined name for this image.
               Names starting with "ibm-" are not allowed. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.file = file
        self.operating_system = operating_system

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImagePrototypeImageByFile':
        """Initialize a ImagePrototypeImageByFile object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'file' in _dict:
            args['file'] = ImageFilePrototype.from_dict(_dict.get('file'))
        else:
            raise ValueError(
                'Required property \'file\' not present in ImagePrototypeImageByFile JSON'
            )
        if 'operating_system' in _dict:
            args['operating_system'] = _dict.get('operating_system')
        else:
            raise ValueError(
                'Required property \'operating_system\' not present in ImagePrototypeImageByFile JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImagePrototypeImageByFile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'file') and self.file is not None:
            _dict['file'] = self.file.to_dict()
        if hasattr(self,
                   'operating_system') and self.operating_system is not None:
            if isinstance(self.operating_system, dict):
                _dict['operating_system'] = self.operating_system
            else:
                _dict['operating_system'] = self.operating_system.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImagePrototypeImageByFile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImagePrototypeImageByFile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImagePrototypeImageByFile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype(
        InstanceGroupManagerPolicyPrototype):
    """
    InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype.

    :attr str name: (optional) The user-defined name for this instance group manager
          policy. Names must be unique within the instance group manager.
    :attr str metric_type: The type of metric to be evaluated.
    :attr int metric_value: The metric value to be evaluated.
    :attr str policy_type: The type of Policy for the Instance Group.
    """

    def __init__(self,
                 metric_type: str,
                 metric_value: int,
                 policy_type: str,
                 *,
                 name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object.

        :param str metric_type: The type of metric to be evaluated.
        :param int metric_value: The metric value to be evaluated.
        :param str policy_type: The type of Policy for the Instance Group.
        :param str name: (optional) The user-defined name for this instance group
               manager policy. Names must be unique within the instance group manager.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.metric_type = metric_type
        self.metric_value = metric_value
        self.policy_type = policy_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype':
        """Initialize a InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'metric_type' in _dict:
            args['metric_type'] = _dict.get('metric_type')
        else:
            raise ValueError(
                'Required property \'metric_type\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON'
            )
        if 'metric_value' in _dict:
            args['metric_value'] = _dict.get('metric_value')
        else:
            raise ValueError(
                'Required property \'metric_value\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON'
            )
        if 'policy_type' in _dict:
            args['policy_type'] = _dict.get('policy_type')
        else:
            raise ValueError(
                'Required property \'policy_type\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'metric_type') and self.metric_type is not None:
            _dict['metric_type'] = self.metric_type
        if hasattr(self, 'metric_value') and self.metric_value is not None:
            _dict['metric_value'] = self.metric_value
        if hasattr(self, 'policy_type') and self.policy_type is not None:
            _dict['policy_type'] = self.policy_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MetricTypeEnum(str, Enum):
        """
        The type of metric to be evaluated.
        """
        CPU = 'cpu'
        MEMORY = 'memory'
        NETWORK_IN = 'network_in'
        NETWORK_OUT = 'network_out'

    class PolicyTypeEnum(str, Enum):
        """
        The type of Policy for the Instance Group.
        """
        TARGET = 'target'


class InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy(
        InstanceGroupManagerPolicy):
    """
    InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy.

    :attr str id: The unique identifier for this instance group manager policy.
    :attr str href: The URL for this instance group manager policy.
    :attr str name: The user-defined name for this instance group manager policy.
          Names must be unique within the instance group manager.
    :attr str metric_type: The type of metric to be evaluated.
    :attr int metric_value: The metric value to be evaluated.
    :attr str policy_type: The type of Policy for the Instance Group.
    """

    def __init__(self, id: str, href: str, name: str, metric_type: str,
                 metric_value: int, policy_type: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object.

        :param str id: The unique identifier for this instance group manager
               policy.
        :param str href: The URL for this instance group manager policy.
        :param str name: The user-defined name for this instance group manager
               policy. Names must be unique within the instance group manager.
        :param str metric_type: The type of metric to be evaluated.
        :param int metric_value: The metric value to be evaluated.
        :param str policy_type: The type of Policy for the Instance Group.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.metric_type = metric_type
        self.metric_value = metric_value
        self.policy_type = policy_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy':
        """Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON'
            )
        if 'metric_type' in _dict:
            args['metric_type'] = _dict.get('metric_type')
        else:
            raise ValueError(
                'Required property \'metric_type\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON'
            )
        if 'metric_value' in _dict:
            args['metric_value'] = _dict.get('metric_value')
        else:
            raise ValueError(
                'Required property \'metric_value\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON'
            )
        if 'policy_type' in _dict:
            args['policy_type'] = _dict.get('policy_type')
        else:
            raise ValueError(
                'Required property \'policy_type\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'metric_type') and self.metric_type is not None:
            _dict['metric_type'] = self.metric_type
        if hasattr(self, 'metric_value') and self.metric_value is not None:
            _dict['metric_value'] = self.metric_value
        if hasattr(self, 'policy_type') and self.policy_type is not None:
            _dict['policy_type'] = self.policy_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MetricTypeEnum(str, Enum):
        """
        The type of metric to be evaluated.
        """
        CPU = 'cpu'
        MEMORY = 'memory'
        NETWORK_IN = 'network_in'
        NETWORK_OUT = 'network_out'

    class PolicyTypeEnum(str, Enum):
        """
        The type of Policy for the Instance Group.
        """
        TARGET = 'target'


class InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype(
        InstanceGroupManagerPrototype):
    """
    InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype.

    :attr str name: (optional) The user-defined name for this instance group
          manager. Names must be unique within the instance group.
    :attr bool management_enabled: (optional) If set to `true`, this manager will
          control the instance group.
    :attr int aggregation_window: (optional) The time window in seconds to aggregate
          metrics prior to evaluation.
    :attr int cooldown: (optional) The duration of time in seconds to pause further
          scale actions after scaling has taken place.
    :attr int max_membership_count: The maximum number of members in a managed
          instance group.
    :attr int min_membership_count: (optional) The minimum number of members in a
          managed instance group.
    :attr str manager_type: The type of instance group manager.
    """

    def __init__(self,
                 max_membership_count: int,
                 manager_type: str,
                 *,
                 name: str = None,
                 management_enabled: bool = None,
                 aggregation_window: int = None,
                 cooldown: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object.

        :param int max_membership_count: The maximum number of members in a managed
               instance group.
        :param str manager_type: The type of instance group manager.
        :param str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within the instance group.
        :param bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        :param int aggregation_window: (optional) The time window in seconds to
               aggregate metrics prior to evaluation.
        :param int cooldown: (optional) The duration of time in seconds to pause
               further scale actions after scaling has taken place.
        :param int min_membership_count: (optional) The minimum number of members
               in a managed instance group.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.management_enabled = management_enabled
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.manager_type = manager_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype':
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        else:
            raise ValueError(
                'Required property \'max_membership_count\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON'
            )
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError(
                'Required property \'manager_type\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(
                self,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(
                self,
                'aggregation_window') and self.aggregation_window is not None:
            _dict['aggregation_window'] = self.aggregation_window
        if hasattr(self, 'cooldown') and self.cooldown is not None:
            _dict['cooldown'] = self.cooldown
        if hasattr(self, 'max_membership_count'
                  ) and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count'
                  ) and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        if hasattr(self, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ManagerTypeEnum(str, Enum):
        """
        The type of instance group manager.
        """
        AUTOSCALE = 'autoscale'


class InstanceProfileBandwidthDependent(InstanceProfileBandwidth):
    """
    The total bandwidth shared across the network interfaces of an instance with this
    profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a InstanceProfileBandwidthDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthDependent':
        """Initialize a InstanceProfileBandwidthDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileBandwidthDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        DEPENDENT = 'dependent'


class InstanceProfileBandwidthEnum(InstanceProfileBandwidth):
    """
    The permitted total bandwidth values (in megabits per second) shared across the
    network interfaces of an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int default: The default value for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, type: str, default: int, values: List[int]) -> None:
        """
        Initialize a InstanceProfileBandwidthEnum object.

        :param str type: The type for this profile field.
        :param int default: The default value for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.default = default
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthEnum':
        """Initialize a InstanceProfileBandwidthEnum object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileBandwidthEnum JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileBandwidthEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileBandwidthEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        ENUM = 'enum'


class InstanceProfileBandwidthFixed(InstanceProfileBandwidth):
    """
    The total bandwidth (in megabits per second) shared across the network interfaces of
    an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(self, type: str, value: int) -> None:
        """
        Initialize a InstanceProfileBandwidthFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthFixed':
        """Initialize a InstanceProfileBandwidthFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileBandwidthFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfileBandwidthFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        FIXED = 'fixed'


class InstanceProfileBandwidthRange(InstanceProfileBandwidth):
    """
    The permitted total bandwidth range (in megabits per second) shared across the network
    interfaces of an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    """

    def __init__(self, type: str, default: int, max: int, min: int,
                 step: int) -> None:
        """
        Initialize a InstanceProfileBandwidthRange object.

        :param str type: The type for this profile field.
        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.default = default
        self.max = max
        self.min = min
        self.step = step

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthRange':
        """Initialize a InstanceProfileBandwidthRange object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileBandwidthRange JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileBandwidthRange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in InstanceProfileBandwidthRange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in InstanceProfileBandwidthRange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in InstanceProfileBandwidthRange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        RANGE = 'range'


class InstanceProfileIdentityByHref(InstanceProfileIdentity):
    """
    InstanceProfileIdentityByHref.

    :attr str href: The URL for this virtual server instance profile.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceProfileIdentityByHref object.

        :param str href: The URL for this virtual server instance profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileIdentityByHref':
        """Initialize a InstanceProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceProfileIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileIdentityByName(InstanceProfileIdentity):
    """
    InstanceProfileIdentityByName.

    :attr str name: The name for this virtual server instance profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a InstanceProfileIdentityByName object.

        :param str name: The name for this virtual server instance profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileIdentityByName':
        """Initialize a InstanceProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceProfileIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileMemoryDependent(InstanceProfileMemory):
    """
    The memory value for an instance with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a InstanceProfileMemoryDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryDependent':
        """Initialize a InstanceProfileMemoryDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileMemoryDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        DEPENDENT = 'dependent'


class InstanceProfileMemoryEnum(InstanceProfileMemory):
    """
    The permitted memory values (in gigabytes) for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int default: The default value for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, type: str, default: int, values: List[int]) -> None:
        """
        Initialize a InstanceProfileMemoryEnum object.

        :param str type: The type for this profile field.
        :param int default: The default value for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.default = default
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryEnum':
        """Initialize a InstanceProfileMemoryEnum object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileMemoryEnum JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileMemoryEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileMemoryEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        ENUM = 'enum'


class InstanceProfileMemoryFixed(InstanceProfileMemory):
    """
    The memory (in gigabytes) for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(self, type: str, value: int) -> None:
        """
        Initialize a InstanceProfileMemoryFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryFixed':
        """Initialize a InstanceProfileMemoryFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileMemoryFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfileMemoryFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        FIXED = 'fixed'


class InstanceProfileMemoryRange(InstanceProfileMemory):
    """
    The permitted memory range (in gigabytes) for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    """

    def __init__(self, type: str, default: int, max: int, min: int,
                 step: int) -> None:
        """
        Initialize a InstanceProfileMemoryRange object.

        :param str type: The type for this profile field.
        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.default = default
        self.max = max
        self.min = min
        self.step = step

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryRange':
        """Initialize a InstanceProfileMemoryRange object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileMemoryRange JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileMemoryRange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in InstanceProfileMemoryRange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in InstanceProfileMemoryRange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in InstanceProfileMemoryRange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        RANGE = 'range'


class InstanceProfilePortSpeedDependent(InstanceProfilePortSpeed):
    """
    The port speed of each network interface of an instance with this profile depends on
    its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a InstanceProfilePortSpeedDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfilePortSpeedDependent':
        """Initialize a InstanceProfilePortSpeedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfilePortSpeedDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfilePortSpeedDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfilePortSpeedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfilePortSpeedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfilePortSpeedDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        DEPENDENT = 'dependent'


class InstanceProfilePortSpeedFixed(InstanceProfilePortSpeed):
    """
    The maximum speed (in megabits per second) of each network interface of an instance
    with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(self, type: str, value: int) -> None:
        """
        Initialize a InstanceProfilePortSpeedFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfilePortSpeedFixed':
        """Initialize a InstanceProfilePortSpeedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfilePortSpeedFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfilePortSpeedFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfilePortSpeedFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfilePortSpeedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfilePortSpeedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfilePortSpeedFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        FIXED = 'fixed'


class InstanceProfileVCPUDependent(InstanceProfileVCPU):
    """
    The VCPU count for an instance with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a InstanceProfileVCPUDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUDependent':
        """Initialize a InstanceProfileVCPUDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileVCPUDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        DEPENDENT = 'dependent'


class InstanceProfileVCPUEnum(InstanceProfileVCPU):
    """
    The permitted values for VCPU count for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int default: The default value for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, type: str, default: int, values: List[int]) -> None:
        """
        Initialize a InstanceProfileVCPUEnum object.

        :param str type: The type for this profile field.
        :param int default: The default value for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.default = default
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUEnum':
        """Initialize a InstanceProfileVCPUEnum object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileVCPUEnum JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileVCPUEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileVCPUEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        ENUM = 'enum'


class InstanceProfileVCPUFixed(InstanceProfileVCPU):
    """
    The VCPU count for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(self, type: str, value: int) -> None:
        """
        Initialize a InstanceProfileVCPUFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUFixed':
        """Initialize a InstanceProfileVCPUFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileVCPUFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfileVCPUFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        FIXED = 'fixed'


class InstanceProfileVCPURange(InstanceProfileVCPU):
    """
    The permitted range for VCPU count for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    """

    def __init__(self, type: str, default: int, max: int, min: int,
                 step: int) -> None:
        """
        Initialize a InstanceProfileVCPURange object.

        :param str type: The type for this profile field.
        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.default = default
        self.max = max
        self.min = min
        self.step = step

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPURange':
        """Initialize a InstanceProfileVCPURange object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileVCPURange JSON'
            )
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileVCPURange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in InstanceProfileVCPURange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in InstanceProfileVCPURange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in InstanceProfileVCPURange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPURange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPURange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPURange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPURange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        RANGE = 'range'


class InstancePrototypeInstanceByImage(InstancePrototype):
    """
    InstancePrototypeInstanceByImage.

    :attr str name: (optional) The unique user-defined name for this virtual server
          instance (and default system hostname). If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr NetworkInterfacePrototype primary_network_interface: Primary network
          interface.
    :attr ZoneIdentity zone: The identity of the zone to provision the virtual
          server instance in.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: The identity of the image to be used when
          provisioning the virtual server instance.
    """

    def __init__(
        self,
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        image: 'ImageIdentity',
        *,
        name: str = None,
        keys: List['KeyIdentity'] = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        profile: 'InstanceProfileIdentity' = None,
        user_data: str = None,
        volume_attachments: List[
            'VolumeAttachmentPrototypeInstanceContext'] = None,
        vpc: 'VPCIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        boot_volume_attachment:
        'VolumeAttachmentPrototypeInstanceByImageContext' = None
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByImage object.

        :param NetworkInterfacePrototype primary_network_interface: Primary network
               interface.
        :param ZoneIdentity zone: The identity of the zone to provision the virtual
               server instance in.
        :param ImageIdentity image: The identity of the image to be used when
               provisioning the virtual server instance.
        :param str name: (optional) The unique user-defined name for this virtual
               server instance (and default system hostname). If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment for the
               virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.keys = keys
        self.network_interfaces = network_interfaces
        self.profile = profile
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.resource_group = resource_group
        self.primary_network_interface = primary_network_interface
        self.zone = zone
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByImage':
        """Initialize a InstancePrototypeInstanceByImage object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentPrototypeInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        else:
            raise ValueError(
                'Required property \'primary_network_interface\' not present in InstancePrototypeInstanceByImage JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in InstancePrototypeInstanceByImage JSON'
            )
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        else:
            raise ValueError(
                'Required property \'image\' not present in InstancePrototypeInstanceByImage JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByImage object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByImage object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByImage') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByImage') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePrototypeInstanceBySourceTemplate(InstancePrototype):
    """
    InstancePrototypeInstanceBySourceTemplate.

    :attr str name: (optional) The unique user-defined name for this virtual server
          instance (and default system hostname). If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) Primary
          network interface.
    :attr ZoneIdentity zone: (optional) The identity of the zone to provision the
          virtual server instance in.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: (optional) The identity of the image to be used when
          provisioning the virtual server instance.
    :attr InstanceTemplateIdentity source_template: Identifies an instance template
          by a unique property.
    """

    def __init__(self,
                 source_template: 'InstanceTemplateIdentity',
                 *,
                 name: str = None,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 primary_network_interface: 'NetworkInterfacePrototype' = None,
                 zone: 'ZoneIdentity' = None,
                 boot_volume_attachment:
                 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
                 image: 'ImageIdentity' = None) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceTemplate object.

        :param InstanceTemplateIdentity source_template: Identifies an instance
               template by a unique property.
        :param str name: (optional) The unique user-defined name for this virtual
               server instance (and default system hostname). If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param NetworkInterfacePrototype primary_network_interface: (optional)
               Primary network interface.
        :param ZoneIdentity zone: (optional) The identity of the zone to provision
               the virtual server instance in.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment for the
               virtual server instance.
        :param ImageIdentity image: (optional) The identity of the image to be used
               when provisioning the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.keys = keys
        self.network_interfaces = network_interfaces
        self.profile = profile
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.resource_group = resource_group
        self.primary_network_interface = primary_network_interface
        self.zone = zone
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.source_template = source_template

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstancePrototypeInstanceBySourceTemplate':
        """Initialize a InstancePrototypeInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentPrototypeInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError(
                'Required property \'source_template\' not present in InstancePrototypeInstanceBySourceTemplate JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceBySourceTemplate object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        if hasattr(self,
                   'source_template') and self.source_template is not None:
            if isinstance(self.source_template, dict):
                _dict['source_template'] = self.source_template
            else:
                _dict['source_template'] = self.source_template.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceBySourceTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstancePrototypeInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstancePrototypeInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentityByCRN(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityByCRN.

    :attr str crn: The CRN for this instance template.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a InstanceTemplateIdentityByCRN object.

        :param str crn: The CRN for this instance template.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateIdentityByCRN':
        """Initialize a InstanceTemplateIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceTemplateIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentityByHref(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityByHref.

    :attr str href: The URL for this instance template.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceTemplateIdentityByHref object.

        :param str href: The URL for this instance template.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateIdentityByHref':
        """Initialize a InstanceTemplateIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentityById(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityById.

    :attr str id: The unique identifier for this instance template.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a InstanceTemplateIdentityById object.

        :param str id: The unique identifier for this instance template.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateIdentityById':
        """Initialize a InstanceTemplateIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototypeInstanceByImage(InstanceTemplatePrototype):
    """
    InstanceTemplatePrototypeInstanceByImage.

    :attr str name: (optional) The unique user-defined name for this virtual server
          instance (and default system hostname). If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr NetworkInterfacePrototype primary_network_interface: Primary network
          interface.
    :attr ZoneIdentity zone: The identity of the zone to provision the virtual
          server instance in.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: The identity of the image to be used when
          provisioning the virtual server instance.
    """

    def __init__(
        self,
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        image: 'ImageIdentity',
        *,
        name: str = None,
        keys: List['KeyIdentity'] = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        profile: 'InstanceProfileIdentity' = None,
        user_data: str = None,
        volume_attachments: List[
            'VolumeAttachmentPrototypeInstanceContext'] = None,
        vpc: 'VPCIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        boot_volume_attachment:
        'VolumeAttachmentPrototypeInstanceByImageContext' = None
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceByImage object.

        :param NetworkInterfacePrototype primary_network_interface: Primary network
               interface.
        :param ZoneIdentity zone: The identity of the zone to provision the virtual
               server instance in.
        :param ImageIdentity image: The identity of the image to be used when
               provisioning the virtual server instance.
        :param str name: (optional) The unique user-defined name for this virtual
               server instance (and default system hostname). If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment for the
               virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.keys = keys
        self.network_interfaces = network_interfaces
        self.profile = profile
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.resource_group = resource_group
        self.primary_network_interface = primary_network_interface
        self.zone = zone
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceTemplatePrototypeInstanceByImage':
        """Initialize a InstanceTemplatePrototypeInstanceByImage object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentPrototypeInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        else:
            raise ValueError(
                'Required property \'primary_network_interface\' not present in InstanceTemplatePrototypeInstanceByImage JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in InstanceTemplatePrototypeInstanceByImage JSON'
            )
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        else:
            raise ValueError(
                'Required property \'image\' not present in InstanceTemplatePrototypeInstanceByImage JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceByImage object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceByImage object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceByImage') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceByImage') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototypeInstanceBySourceTemplate(
        InstanceTemplatePrototype):
    """
    InstanceTemplatePrototypeInstanceBySourceTemplate.

    :attr str name: (optional) The unique user-defined name for this virtual server
          instance (and default system hostname). If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) Primary
          network interface.
    :attr ZoneIdentity zone: (optional) The identity of the zone to provision the
          virtual server instance in.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: (optional) The identity of the image to be used when
          provisioning the virtual server instance.
    :attr InstanceTemplateIdentity source_template: Identifies an instance template
          by a unique property.
    """

    def __init__(self,
                 source_template: 'InstanceTemplateIdentity',
                 *,
                 name: str = None,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 primary_network_interface: 'NetworkInterfacePrototype' = None,
                 zone: 'ZoneIdentity' = None,
                 boot_volume_attachment:
                 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
                 image: 'ImageIdentity' = None) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceBySourceTemplate object.

        :param InstanceTemplateIdentity source_template: Identifies an instance
               template by a unique property.
        :param str name: (optional) The unique user-defined name for this virtual
               server instance (and default system hostname). If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param NetworkInterfacePrototype primary_network_interface: (optional)
               Primary network interface.
        :param ZoneIdentity zone: (optional) The identity of the zone to provision
               the virtual server instance in.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment for the
               virtual server instance.
        :param ImageIdentity image: (optional) The identity of the image to be used
               when provisioning the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.keys = keys
        self.network_interfaces = network_interfaces
        self.profile = profile
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.resource_group = resource_group
        self.primary_network_interface = primary_network_interface
        self.zone = zone
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.source_template = source_template

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceTemplatePrototypeInstanceBySourceTemplate':
        """Initialize a InstanceTemplatePrototypeInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentPrototypeInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError(
                'Required property \'source_template\' not present in InstanceTemplatePrototypeInstanceBySourceTemplate JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceBySourceTemplate object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        if hasattr(self,
                   'source_template') and self.source_template is not None:
            if isinstance(self.source_template, dict):
                _dict['source_template'] = self.source_template
            else:
                _dict['source_template'] = self.source_template.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceBySourceTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'InstanceTemplatePrototypeInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'InstanceTemplatePrototypeInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateInstanceByImage(InstanceTemplate):
    """
    InstanceTemplateInstanceByImage.

    :attr str id: The unique identifier for this instance template.
    :attr str href: The URL for this instance template.
    :attr str crn: The CRN for this instance template.
    :attr str name: The unique user-defined name for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :attr NetworkInterfacePrototype primary_network_interface: Primary network
          interface.
    :attr ZoneIdentity zone: The identity of the zone to provision the virtual
          server instance in.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: The identity of the image to be used when
          provisioning the virtual server instance.
    """

    def __init__(
        self,
        id: str,
        href: str,
        crn: str,
        name: str,
        created_at: datetime,
        resource_group: 'ResourceGroupReference',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        image: 'ImageIdentity',
        *,
        keys: List['KeyIdentity'] = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        profile: 'InstanceProfileIdentity' = None,
        user_data: str = None,
        volume_attachments: List[
            'VolumeAttachmentPrototypeInstanceContext'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment:
        'VolumeAttachmentPrototypeInstanceByImageContext' = None
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByImage object.

        :param str id: The unique identifier for this instance template.
        :param str href: The URL for this instance template.
        :param str crn: The CRN for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :param datetime created_at: The date and time that the instance template
               was created.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param NetworkInterfacePrototype primary_network_interface: Primary network
               interface.
        :param ZoneIdentity zone: The identity of the zone to provision the virtual
               server instance in.
        :param ImageIdentity image: The identity of the image to be used when
               provisioning the virtual server instance.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment for the
               virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.crn = crn
        self.name = name
        self.keys = keys
        self.network_interfaces = network_interfaces
        self.profile = profile
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.created_at = created_at
        self.resource_group = resource_group
        self.primary_network_interface = primary_network_interface
        self.zone = zone
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByImage':
        """Initialize a InstanceTemplateInstanceByImage object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentPrototypeInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        else:
            raise ValueError(
                'Required property \'primary_network_interface\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        else:
            raise ValueError(
                'Required property \'image\' not present in InstanceTemplateInstanceByImage JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByImage object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceByImage object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByImage') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByImage') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateInstanceBySourceTemplate(InstanceTemplate):
    """
    InstanceTemplateInstanceBySourceTemplate.

    :attr str id: The unique identifier for this instance template.
    :attr str href: The URL for this instance template.
    :attr str crn: The CRN for this instance template.
    :attr str name: The unique user-defined name for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. Up to 10 keys may be
          provided; if no keys are provided the instance will be inaccessible unless the
          image used provides another means of access. For Windows instances, one of the
          keys will be used to encrypt the administrator password.
          Keys will be made available to the virtual server instance as cloud-init vendor
          data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr str user_data: (optional) User data to be made available when setting up
          the virtual server instance.
    :attr List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
          (optional) Collection of volume attachments.
    :attr VPCIdentity vpc: (optional) The VPC the virtual server instance is to be a
          part of. If provided, must match the
          VPC tied to the subnets of the instance's network interfaces.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) Primary
          network interface.
    :attr ZoneIdentity zone: (optional) The identity of the zone to provision the
          virtual server instance in.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: (optional) The identity of the image to be used when
          provisioning the virtual server instance.
    :attr InstanceTemplateIdentity source_template: Identifies an instance template
          by a unique property.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 crn: str,
                 name: str,
                 created_at: datetime,
                 resource_group: 'ResourceGroupReference',
                 source_template: 'InstanceTemplateIdentity',
                 *,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 primary_network_interface: 'NetworkInterfacePrototype' = None,
                 zone: 'ZoneIdentity' = None,
                 boot_volume_attachment:
                 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
                 image: 'ImageIdentity' = None) -> None:
        """
        Initialize a InstanceTemplateInstanceBySourceTemplate object.

        :param str id: The unique identifier for this instance template.
        :param str href: The URL for this instance template.
        :param str crn: The CRN for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :param datetime created_at: The date and time that the instance template
               was created.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param InstanceTemplateIdentity source_template: Identifies an instance
               template by a unique property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. Up to 10 keys may be
               provided; if no keys are provided the instance will be inaccessible unless
               the image used provides another means of access. For Windows instances, one
               of the keys will be used to encrypt the administrator password.
               Keys will be made available to the virtual server instance as cloud-init
               vendor data. For cloud-init enabled images, these keys will also be added
               as SSH authorized keys for the administrative user.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param str user_data: (optional) User data to be made available when
               setting up the virtual server instance.
        :param List[VolumeAttachmentPrototypeInstanceContext] volume_attachments:
               (optional) Collection of volume attachments.
        :param VPCIdentity vpc: (optional) The VPC the virtual server instance is
               to be a part of. If provided, must match the
               VPC tied to the subnets of the instance's network interfaces.
        :param NetworkInterfacePrototype primary_network_interface: (optional)
               Primary network interface.
        :param ZoneIdentity zone: (optional) The identity of the zone to provision
               the virtual server instance in.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment for the
               virtual server instance.
        :param ImageIdentity image: (optional) The identity of the image to be used
               when provisioning the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.crn = crn
        self.name = name
        self.keys = keys
        self.network_interfaces = network_interfaces
        self.profile = profile
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.created_at = created_at
        self.resource_group = resource_group
        self.primary_network_interface = primary_network_interface
        self.zone = zone
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.source_template = source_template

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceTemplateInstanceBySourceTemplate':
        """Initialize a InstanceTemplateInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [
                VolumeAttachmentPrototypeInstanceContext.from_dict(x)
                for x in _dict.get('volume_attachments')
            ]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        if 'boot_volume_attachment' in _dict:
            args[
                'boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(
                    _dict.get('boot_volume_attachment'))
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError(
                'Required property \'source_template\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceBySourceTemplate object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for x in self.keys:
                if isinstance(x, dict):
                    keys_list.append(x)
                else:
                    keys_list.append(x.to_dict())
            _dict['keys'] = keys_list
        if hasattr(
                self,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        if hasattr(
                self,
                'volume_attachments') and self.volume_attachments is not None:
            _dict['volume_attachments'] = [
                x.to_dict() for x in self.volume_attachments
            ]
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.to_dict(
                )
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'boot_volume_attachment'
                  ) and self.boot_volume_attachment is not None:
            _dict[
                'boot_volume_attachment'] = self.boot_volume_attachment.to_dict(
                )
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        if hasattr(self,
                   'source_template') and self.source_template is not None:
            if isinstance(self.source_template, dict):
                _dict['source_template'] = self.source_template
            else:
                _dict['source_template'] = self.source_template.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceBySourceTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyIdentityByCRN(KeyIdentity):
    """
    KeyIdentityByCRN.

    :attr str crn: The CRN for this key.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a KeyIdentityByCRN object.

        :param str crn: The CRN for this key.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyIdentityByCRN':
        """Initialize a KeyIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in KeyIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyIdentityByHref(KeyIdentity):
    """
    KeyIdentityByHref.

    :attr str href: The URL for this key.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a KeyIdentityByHref object.

        :param str href: The URL for this key.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyIdentityByHref':
        """Initialize a KeyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in KeyIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyIdentityById(KeyIdentity):
    """
    KeyIdentityById.

    :attr str id: The unique identifier for this key.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a KeyIdentityById object.

        :param str id: The unique identifier for this key.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyIdentityById':
        """Initialize a KeyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in KeyIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyIdentityKeyIdentityByFingerprint(KeyIdentity):
    """
    KeyIdentityKeyIdentityByFingerprint.

    :attr str fingerprint: The fingerprint for this key.  The value is returned
          base64-encoded and prefixed with the hash algorithm (always `SHA256`).
    """

    def __init__(self, fingerprint: str) -> None:
        """
        Initialize a KeyIdentityKeyIdentityByFingerprint object.

        :param str fingerprint: The fingerprint for this key.  The value is
               returned base64-encoded and prefixed with the hash algorithm (always
               `SHA256`).
        """
        # pylint: disable=super-init-not-called
        self.fingerprint = fingerprint

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyIdentityKeyIdentityByFingerprint':
        """Initialize a KeyIdentityKeyIdentityByFingerprint object from a json dictionary."""
        args = {}
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError(
                'Required property \'fingerprint\' not present in KeyIdentityKeyIdentityByFingerprint JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyIdentityKeyIdentityByFingerprint object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyIdentityKeyIdentityByFingerprint object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyIdentityKeyIdentityByFingerprint') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyIdentityKeyIdentityByFingerprint') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint(
        KeyReferenceInstanceInitializationContext):
    """
    KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint.

    :attr str fingerprint: The fingerprint for this key.  The value is returned
          base64-encoded and prefixed with the hash algorithm (always `SHA256`).
    """

    def __init__(self, fingerprint: str) -> None:
        """
        Initialize a KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint object.

        :param str fingerprint: The fingerprint for this key.  The value is
               returned base64-encoded and prefixed with the hash algorithm (always
               `SHA256`).
        """
        # pylint: disable=super-init-not-called
        self.fingerprint = fingerprint

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint':
        """Initialize a KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint object from a json dictionary."""
        args = {}
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError(
                'Required property \'fingerprint\' not present in KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'KeyReferenceInstanceInitializationContextKeyIdentityByFingerprint'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyReferenceInstanceInitializationContextKeyReference(
        KeyReferenceInstanceInitializationContext):
    """
    KeyReferenceInstanceInitializationContextKeyReference.

    :attr str id: The unique identifier for this key.
    :attr str crn: The CRN for this key.
    :attr str href: The URL for this key.
    :attr str fingerprint: The fingerprint for this key.  The value is returned
          base64-encoded and prefixed with the hash algorithm (always `SHA256`).
    :attr str name: The user-defined name for this key.
    """

    def __init__(self, id: str, crn: str, href: str, fingerprint: str,
                 name: str) -> None:
        """
        Initialize a KeyReferenceInstanceInitializationContextKeyReference object.

        :param str id: The unique identifier for this key.
        :param str crn: The CRN for this key.
        :param str href: The URL for this key.
        :param str fingerprint: The fingerprint for this key.  The value is
               returned base64-encoded and prefixed with the hash algorithm (always
               `SHA256`).
        :param str name: The user-defined name for this key.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.fingerprint = fingerprint
        self.name = name

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'KeyReferenceInstanceInitializationContextKeyReference':
        """Initialize a KeyReferenceInstanceInitializationContextKeyReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in KeyReferenceInstanceInitializationContextKeyReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in KeyReferenceInstanceInitializationContextKeyReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in KeyReferenceInstanceInitializationContextKeyReference JSON'
            )
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError(
                'Required property \'fingerprint\' not present in KeyReferenceInstanceInitializationContextKeyReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in KeyReferenceInstanceInitializationContextKeyReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyReferenceInstanceInitializationContextKeyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyReferenceInstanceInitializationContextKeyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'KeyReferenceInstanceInitializationContextKeyReference'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'KeyReferenceInstanceInitializationContextKeyReference'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentityByCRN(LoadBalancerIdentity):
    """
    LoadBalancerIdentityByCRN.

    :attr str crn: The load balancer's CRN.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a LoadBalancerIdentityByCRN object.

        :param str crn: The load balancer's CRN.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerIdentityByCRN':
        """Initialize a LoadBalancerIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in LoadBalancerIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentityByHref(LoadBalancerIdentity):
    """
    LoadBalancerIdentityByHref.

    :attr str href: The load balancer's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerIdentityByHref object.

        :param str href: The load balancer's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerIdentityByHref':
        """Initialize a LoadBalancerIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentityById(LoadBalancerIdentity):
    """
    LoadBalancerIdentityById.

    :attr str id: The unique identifier for this load balancer.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerIdentityById object.

        :param str id: The unique identifier for this load balancer.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerIdentityById':
        """Initialize a LoadBalancerIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch(
        LoadBalancerListenerPolicyPatchTarget):
    """
    LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch.

    :attr int http_status_code: (optional) The http status code in the redirect
          response.
    :attr str url: (optional) The redirect target URL.
    """

    def __init__(self,
                 *,
                 http_status_code: int = None,
                 url: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch object.

        :param int http_status_code: (optional) The http status code in the
               redirect response.
        :param str url: (optional) The redirect target URL.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.url = url

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch':
        """Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch object from a json dictionary."""
        args = {}
        if 'http_status_code' in _dict:
            args['http_status_code'] = _dict.get('http_status_code')
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'http_status_code') and self.http_status_code is not None:
            _dict['http_status_code'] = self.http_status_code
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentity(
        LoadBalancerListenerPolicyPatchTarget):
    """
    Identifies a load balancer pool by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById',
                'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype(
        LoadBalancerListenerPolicyPrototypeTarget):
    """
    LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype.

    :attr int http_status_code: The http status code in the redirect response.
    :attr str url: The redirect target URL.
    """

    def __init__(self, http_status_code: int, url: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype object.

        :param int http_status_code: The http status code in the redirect response.
        :param str url: The redirect target URL.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.url = url

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype':
        """Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype object from a json dictionary."""
        args = {}
        if 'http_status_code' in _dict:
            args['http_status_code'] = _dict.get('http_status_code')
        else:
            raise ValueError(
                'Required property \'http_status_code\' not present in LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype JSON'
            )
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        else:
            raise ValueError(
                'Required property \'url\' not present in LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'http_status_code') and self.http_status_code is not None:
            _dict['http_status_code'] = self.http_status_code
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerListenerPolicyRedirectURLPrototype'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentity(
        LoadBalancerListenerPolicyPrototypeTarget):
    """
    Identifies a load balancer pool by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById',
                'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL(
        LoadBalancerListenerPolicyTargetReference):
    """
    LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL.

    :attr int http_status_code: The http status code in the redirect response.
    :attr str url: The redirect target URL.
    """

    def __init__(self, http_status_code: int, url: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL object.

        :param int http_status_code: The http status code in the redirect response.
        :param str url: The redirect target URL.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.url = url

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL':
        """Initialize a LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL object from a json dictionary."""
        args = {}
        if 'http_status_code' in _dict:
            args['http_status_code'] = _dict.get('http_status_code')
        else:
            raise ValueError(
                'Required property \'http_status_code\' not present in LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL JSON'
            )
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        else:
            raise ValueError(
                'Required property \'url\' not present in LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'http_status_code') and self.http_status_code is not None:
            _dict['http_status_code'] = self.http_status_code
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetReferenceLoadBalancerListenerPolicyRedirectURL'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference(
        LoadBalancerListenerPolicyTargetReference):
    """
    LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference.

    :attr str id: The unique identifier for this load balancer pool.
    :attr str href: The pool's canonical URL.
    :attr str name: The user-defined name for this load balancer pool.
    """

    def __init__(self, id: str, href: str, name: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference object.

        :param str id: The unique identifier for this load balancer pool.
        :param str href: The pool's canonical URL.
        :param str name: The user-defined name for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference':
        """Initialize a LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetReferenceLoadBalancerPoolReference'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolIdentityByHref(LoadBalancerPoolIdentity):
    """
    LoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerPoolIdentityByHref object.

        :param str href: The pool's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolIdentityById(LoadBalancerPoolIdentity):
    """
    LoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerPoolIdentityById object.

        :param str id: The unique identifier for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPoolIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeIP(
        LoadBalancerPoolMemberTargetPrototype):
    """
    LoadBalancerPoolMemberTargetPrototypeIP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerPoolMemberTargetPrototypeIP':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in LoadBalancerPoolMemberTargetPrototypeIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetPrototypeIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetPrototypeIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentity(
        LoadBalancerPoolMemberTargetPrototype):
    """
    Identifies a virtual server instance by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById',
                'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN',
                'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerPoolMemberTargetIP(LoadBalancerPoolMemberTarget):
    """
    LoadBalancerPoolMemberTargetIP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetIP':
        """Initialize a LoadBalancerPoolMemberTargetIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in LoadBalancerPoolMemberTargetIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetInstanceReference(LoadBalancerPoolMemberTarget
                                                   ):
    """
    LoadBalancerPoolMemberTargetInstanceReference.

    :attr str id: The unique identifier for this virtual server instance.
    :attr str crn: The CRN for this virtual server instance.
    :attr str href: The URL for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetInstanceReference object.

        :param str id: The unique identifier for this virtual server instance.
        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'LoadBalancerPoolMemberTargetInstanceReference':
        """Initialize a LoadBalancerPoolMemberTargetInstanceReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetInstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'LoadBalancerPoolMemberTargetInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'LoadBalancerPoolMemberTargetInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileIdentityByHref(LoadBalancerProfileIdentity):
    """
    LoadBalancerProfileIdentityByHref.

    :attr str href: The URL for this load balancer profile.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerProfileIdentityByHref object.

        :param str href: The URL for this load balancer profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileIdentityByHref':
        """Initialize a LoadBalancerProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerProfileIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileIdentityByName(LoadBalancerProfileIdentity):
    """
    LoadBalancerProfileIdentityByName.

    :attr str name: The name for this load balancer profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a LoadBalancerProfileIdentityByName object.

        :param str name: The name for this load balancer profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileIdentityByName':
        """Initialize a LoadBalancerProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerProfileIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentityByCRN(NetworkACLIdentity):
    """
    NetworkACLIdentityByCRN.

    :attr str crn: The CRN for this network ACL.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a NetworkACLIdentityByCRN object.

        :param str crn: The CRN for this network ACL.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLIdentityByCRN':
        """Initialize a NetworkACLIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in NetworkACLIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentityByHref(NetworkACLIdentity):
    """
    NetworkACLIdentityByHref.

    :attr str href: The URL for this network ACL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLIdentityByHref object.

        :param str href: The URL for this network ACL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLIdentityByHref':
        """Initialize a NetworkACLIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentityById(NetworkACLIdentity):
    """
    NetworkACLIdentityById.

    :attr str id: The unique identifier for this network ACL.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a NetworkACLIdentityById object.

        :param str id: The unique identifier for this network ACL.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLIdentityById':
        """Initialize a NetworkACLIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLPrototypeNetworkACLByRules(NetworkACLPrototype):
    """
    NetworkACLPrototypeNetworkACLByRules.

    :attr str name: (optional) The user-defined name for this network ACL. Names
          must be unique within the VPC the Network ACL resides in. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr VPCIdentity vpc: The VPC this network ACL is to be a part of.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr List[NetworkACLRulePrototypeNetworkACLContext] rules: (optional) Array of
          prototype objects for rules to create along with this network ACL. If
          unspecified, no rules will be created, resulting in all traffic being denied.
    """

    def __init__(
            self,
            vpc: 'VPCIdentity',
            *,
            name: str = None,
            resource_group: 'ResourceGroupIdentity' = None,
            rules: List['NetworkACLRulePrototypeNetworkACLContext'] = None
    ) -> None:
        """
        Initialize a NetworkACLPrototypeNetworkACLByRules object.

        :param VPCIdentity vpc: The VPC this network ACL is to be a part of.
        :param str name: (optional) The user-defined name for this network ACL.
               Names must be unique within the VPC the Network ACL resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param List[NetworkACLRulePrototypeNetworkACLContext] rules: (optional)
               Array of prototype objects for rules to create along with this network ACL.
               If unspecified, no rules will be created, resulting in all traffic being
               denied.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.vpc = vpc
        self.resource_group = resource_group
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLPrototypeNetworkACLByRules':
        """Initialize a NetworkACLPrototypeNetworkACLByRules object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError(
                'Required property \'vpc\' not present in NetworkACLPrototypeNetworkACLByRules JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'rules' in _dict:
            args['rules'] = [
                NetworkACLRulePrototypeNetworkACLContext.from_dict(x)
                for x in _dict.get('rules')
            ]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLPrototypeNetworkACLByRules object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLPrototypeNetworkACLByRules object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLPrototypeNetworkACLByRules') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLPrototypeNetworkACLByRules') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLPrototypeNetworkACLBySourceNetworkACL(NetworkACLPrototype):
    """
    NetworkACLPrototypeNetworkACLBySourceNetworkACL.

    :attr str name: (optional) The user-defined name for this network ACL. Names
          must be unique within the VPC the Network ACL resides in. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr VPCIdentity vpc: The VPC this network ACL is to be a part of.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr NetworkACLIdentity source_network_acl: Network ACL to copy rules from.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 source_network_acl: 'NetworkACLIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object.

        :param VPCIdentity vpc: The VPC this network ACL is to be a part of.
        :param NetworkACLIdentity source_network_acl: Network ACL to copy rules
               from.
        :param str name: (optional) The user-defined name for this network ACL.
               Names must be unique within the VPC the Network ACL resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.vpc = vpc
        self.resource_group = resource_group
        self.source_network_acl = source_network_acl

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkACLPrototypeNetworkACLBySourceNetworkACL':
        """Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError(
                'Required property \'vpc\' not present in NetworkACLPrototypeNetworkACLBySourceNetworkACL JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'source_network_acl' in _dict:
            args['source_network_acl'] = _dict.get('source_network_acl')
        else:
            raise ValueError(
                'Required property \'source_network_acl\' not present in NetworkACLPrototypeNetworkACLBySourceNetworkACL JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(
                self,
                'source_network_acl') and self.source_network_acl is not None:
            if isinstance(self.source_network_acl, dict):
                _dict['source_network_acl'] = self.source_network_acl
            else:
                _dict['source_network_acl'] = self.source_network_acl.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLPrototypeNetworkACLBySourceNetworkACL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'NetworkACLPrototypeNetworkACLBySourceNetworkACL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'NetworkACLPrototypeNetworkACLBySourceNetworkACL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleIdentityByHref(NetworkACLRuleIdentity):
    """
    NetworkACLRuleIdentityByHref.

    :attr str href: The URL for this Network ACL rule.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleIdentityByHref object.

        :param str href: The URL for this Network ACL rule.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleIdentityByHref':
        """Initialize a NetworkACLRuleIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleIdentityById(NetworkACLRuleIdentity):
    """
    NetworkACLRuleIdentityById.

    :attr str id: The unique identifier for this Network ACL rule.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a NetworkACLRuleIdentityById object.

        :param str id: The unique identifier for this Network ACL rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleIdentityById':
        """Initialize a NetworkACLRuleIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleItemNetworkACLRuleProtocolAll(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolAll.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always
          refers to the next item in the collection. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRuleItemNetworkACLRuleProtocolAll object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. In a rule collection, this always
               refers to the next item in the collection. If absent, this is the last
               rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.created_at = created_at
        self.ip_version = ip_version

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleItemNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(
                _dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleItemNetworkACLRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'NetworkACLRuleItemNetworkACLRuleProtocolAll') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'NetworkACLRuleItemNetworkACLRuleProtocolAll') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRuleItemNetworkACLRuleProtocolICMP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolICMP.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always
          refers to the next item in the collection. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    :attr int code: (optional) The ICMP traffic code to allow. If unspecified, all
          codes are allowed. This can only be specified if type is also specified.
    :attr int type: (optional) The ICMP traffic type to allow. If unspecified, all
          types are allowed by this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRuleItemNetworkACLRuleProtocolICMP object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. In a rule collection, this always
               refers to the next item in the collection. If absent, this is the last
               rule.
        :param int code: (optional) The ICMP traffic code to allow. If unspecified,
               all codes are allowed. This can only be specified if type is also
               specified.
        :param int type: (optional) The ICMP traffic type to allow. If unspecified,
               all types are allowed by this rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.created_at = created_at
        self.ip_version = ip_version
        self.code = code
        self.type = type

    @classmethod
    def from_dict(
            cls, _dict: Dict) -> 'NetworkACLRuleItemNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(
                _dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleItemNetworkACLRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'NetworkACLRuleItemNetworkACLRuleProtocolICMP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'NetworkACLRuleItemNetworkACLRuleProtocolICMP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always
          refers to the next item in the collection. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None,
                 destination_port_max: int = None,
                 destination_port_min: int = None,
                 source_port_max: int = None,
                 source_port_min: int = None) -> None:
        """
        Initialize a NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. In a rule collection, this always
               refers to the next item in the collection. If absent, this is the last
               rule.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.created_at = created_at
        self.ip_version = ip_version
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(
                _dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'destination_port_max'
                  ) and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min'
                  ) and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self,
                   'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self,
                   'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll(
        NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP(
        NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    :attr int code: (optional) The ICMP traffic code to allow. If unspecified, all
          codes are allowed. This can only be specified if type is also specified.
    :attr int type: (optional) The ICMP traffic type to allow. If unspecified, all
          types are allowed by this rule.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param int code: (optional) The ICMP traffic code to allow. If unspecified,
               all codes are allowed. This can only be specified if type is also
               specified.
        :param int type: (optional) The ICMP traffic type to allow. If unspecified,
               all types are allowed by this rule.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.code = code
        self.type = type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP(
        NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None,
                 destination_port_max: int = None,
                 destination_port_min: int = None,
                 source_port_max: int = None,
                 source_port_min: int = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'destination_port_max'
                  ) and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min'
                  ) and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self,
                   'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self,
                   'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLRuleProtocolAll(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolAll.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleIdentity before: (optional) The rule to insert this rule
          immediately before. If omitted, this rule will be
          inserted after all existing rules.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None,
                 before: 'NetworkACLRuleIdentity' = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAll object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLRuleIdentity before: (optional) The rule to insert this
               rule immediately before. If omitted, this rule will be
               inserted after all existing rules.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAll JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAll JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAll JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAll JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAll JSON'
            )
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _dict['before'] = self.before.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolAll') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolAll') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLRuleProtocolICMP(NetworkACLRulePrototype
                                                       ):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolICMP.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleIdentity before: (optional) The rule to insert this rule
          immediately before. If omitted, this rule will be
          inserted after all existing rules.
    :attr int code: (optional) The ICMP traffic code to allow. If unspecified, all
          codes are allowed. This can only be specified if type is also specified.
    :attr int type: (optional) The ICMP traffic type to allow. If unspecified, all
          types are allowed by this rule.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None,
                 before: 'NetworkACLRuleIdentity' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMP object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLRuleIdentity before: (optional) The rule to insert this
               rule immediately before. If omitted, this rule will be
               inserted after all existing rules.
        :param int code: (optional) The ICMP traffic code to allow. If unspecified,
               all codes are allowed. This can only be specified if type is also
               specified.
        :param int type: (optional) The ICMP traffic type to allow. If unspecified,
               all types are allowed by this rule.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.code = code
        self.type = type

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _dict['before'] = self.before.to_dict()
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP(
        NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP.

    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination IP address or CIDR block. The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleIdentity before: (optional) The rule to insert this rule
          immediately before. If omitted, this rule will be
          inserted after all existing rules.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 *,
                 name: str = None,
                 before: 'NetworkACLRuleIdentity' = None,
                 destination_port_max: int = None,
                 destination_port_min: int = None,
                 source_port_max: int = None,
                 source_port_min: int = None) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP object.

        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination IP address or CIDR block. The CIDR
               block `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLRuleIdentity before: (optional) The rule to insert this
               rule immediately before. If omitted, this rule will be
               inserted after all existing rules.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _dict['before'] = self.before.to_dict()
        if hasattr(self, 'destination_port_max'
                  ) and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min'
                  ) and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self,
                   'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self,
                   'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRuleNetworkACLRuleProtocolAll(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolAll.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRuleNetworkACLRuleProtocolAll object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. If absent, this is the last rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.created_at = created_at
        self.ip_version = ip_version

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(
                _dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleNetworkACLRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleNetworkACLRuleProtocolAll') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleNetworkACLRuleProtocolAll') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRuleNetworkACLRuleProtocolICMP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolICMP.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    :attr int code: (optional) The ICMP traffic code to allow. If unspecified, all
          codes are allowed. This can only be specified if type is also specified.
    :attr int type: (optional) The ICMP traffic type to allow. If unspecified, all
          types are allowed by this rule.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRuleNetworkACLRuleProtocolICMP object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. If absent, this is the last rule.
        :param int code: (optional) The ICMP traffic code to allow. If unspecified,
               all codes are allowed. This can only be specified if type is also
               specified.
        :param int type: (optional) The ICMP traffic type to allow. If unspecified,
               all types are allowed by this rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.created_at = created_at
        self.ip_version = ip_version
        self.code = code
        self.type = type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(
                _dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleNetworkACLRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleNetworkACLRuleProtocolICMP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleNetworkACLRuleProtocolICMP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRuleNetworkACLRuleProtocolTCPUDP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolTCPUDP.

    :attr str id: The unique identifier for this Network ACL rule.
    :attr str href: The URL for this Network ACL rule.
    :attr str name: The user-defined name for this rule. Names must be unique within
          the network ACL the rule resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str action: Whether to allow or deny matching traffic.
    :attr str destination: The destination CIDR block. The CIDR block `0.0.0.0/0`
          applies to all addresses.
    :attr str direction: Whether the traffic to be matched is `inbound` or
          `outbound`.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :attr str protocol: The protocol to enforce.
    :attr NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last rule.
    :attr datetime created_at: The date and time that the rule was created.
    :attr str ip_version: The IP version for this rule.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 name: str,
                 action: str,
                 destination: str,
                 direction: str,
                 source: str,
                 protocol: str,
                 created_at: datetime,
                 ip_version: str,
                 *,
                 before: 'NetworkACLRuleReference' = None,
                 destination_port_max: int = None,
                 destination_port_min: int = None,
                 source_port_max: int = None,
                 source_port_min: int = None) -> None:
        """
        Initialize a NetworkACLRuleNetworkACLRuleProtocolTCPUDP object.

        :param str id: The unique identifier for this Network ACL rule.
        :param str href: The URL for this Network ACL rule.
        :param str name: The user-defined name for this rule. Names must be unique
               within the network ACL the rule resides in. If unspecified, the name will
               be a hyphenated list of randomly-selected words.
        :param str action: Whether to allow or deny matching traffic.
        :param str destination: The destination CIDR block. The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param str direction: Whether the traffic to be matched is `inbound` or
               `outbound`.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :param str protocol: The protocol to enforce.
        :param datetime created_at: The date and time that the rule was created.
        :param str ip_version: The IP version for this rule.
        :param NetworkACLRuleReference before: (optional) The rule that this rule
               is immediately before. If absent, this is the last rule.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.name = name
        self.action = action
        self.destination = destination
        self.direction = direction
        self.source = source
        self.protocol = protocol
        self.before = before
        self.created_at = created_at
        self.ip_version = ip_version
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(
                _dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError(
                'Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'destination_port_max'
                  ) and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min'
                  ) and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self,
                   'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self,
                   'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        Whether to allow or deny matching traffic.
        """
        ALLOW = 'allow'
        DENY = 'deny'

    class DirectionEnum(str, Enum):
        """
        Whether the traffic to be matched is `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'

    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class OperatingSystemIdentityByHref(OperatingSystemIdentity):
    """
    OperatingSystemIdentityByHref.

    :attr str href: The URL for this operating system.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a OperatingSystemIdentityByHref object.

        :param str href: The URL for this operating system.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystemIdentityByHref':
        """Initialize a OperatingSystemIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in OperatingSystemIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystemIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystemIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystemIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystemIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystemIdentityByName(OperatingSystemIdentity):
    """
    OperatingSystemIdentityByName.

    :attr str name: The unique name of the operating system.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a OperatingSystemIdentityByName object.

        :param str name: The unique name of the operating system.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystemIdentityByName':
        """Initialize a OperatingSystemIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in OperatingSystemIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystemIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystemIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystemIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystemIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentityByCRN(PublicGatewayIdentity):
    """
    PublicGatewayIdentityByCRN.

    :attr str crn: The CRN for this public gateway.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a PublicGatewayIdentityByCRN object.

        :param str crn: The CRN for this public gateway.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayIdentityByCRN':
        """Initialize a PublicGatewayIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGatewayIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentityByHref(PublicGatewayIdentity):
    """
    PublicGatewayIdentityByHref.

    :attr str href: The URL for this public gateway.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayIdentityByHref object.

        :param str href: The URL for this public gateway.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayIdentityByHref':
        """Initialize a PublicGatewayIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentityById(PublicGatewayIdentity):
    """
    PublicGatewayIdentityById.

    :attr str id: The unique identifier for this public gateway.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a PublicGatewayIdentityById object.

        :param str id: The unique identifier for this public gateway.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayIdentityById':
        """Initialize a PublicGatewayIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in PublicGatewayIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayPrototypeFloatingIpFloatingIPIdentity(
        PublicGatewayPrototypeFloatingIp):
    """
    Identifies a floating IP by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById',
                'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN',
                'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref',
                'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress'
            ]))
        raise Exception(msg)


class PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext(
        PublicGatewayPrototypeFloatingIp):
    """
    PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext.

    :attr str name: (optional) The unique user-defined name for this floating IP. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext object.

        :param str name: (optional) The unique user-defined name for this floating
               IP. If unspecified, the name will be a hyphenated list of randomly-selected
               words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext':
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'PublicGatewayPrototypeFloatingIpFloatingIPPrototypeTargetContext'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ResourceGroupIdentityById(ResourceGroupIdentity):
    """
    ResourceGroupIdentityById.

    :attr str id: The unique identifier for this resource group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a ResourceGroupIdentityById object.

        :param str id: The unique identifier for this resource group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ResourceGroupIdentityById':
        """Initialize a ResourceGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ResourceGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ResourceGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ResourceGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ResourceGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ResourceGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopIP(RouteNextHop):
    """
    RouteNextHopIP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a RouteNextHopIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopIP':
        """Initialize a RouteNextHopIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in RouteNextHopIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteNextHopIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPrototypeRouteNextHopIP(RouteNextHopPrototype):
    """
    The IP address of the next hop to which to route packets. Must be an IP address within
    a subnet assigned to `zone`.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a RouteNextHopPrototypeRouteNextHopIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPrototypeRouteNextHopIP':
        """Initialize a RouteNextHopPrototypeRouteNextHopIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in RouteNextHopPrototypeRouteNextHopIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeRouteNextHopIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteNextHopPrototypeRouteNextHopIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPrototypeRouteNextHopIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPrototypeRouteNextHopIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentityByCRN(SecurityGroupIdentity):
    """
    SecurityGroupIdentityByCRN.

    :attr str crn: The security group's CRN.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a SecurityGroupIdentityByCRN object.

        :param str crn: The security group's CRN.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupIdentityByCRN':
        """Initialize a SecurityGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentityByHref(SecurityGroupIdentity):
    """
    SecurityGroupIdentityByHref.

    :attr str href: The security group's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupIdentityByHref object.

        :param str href: The security group's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupIdentityByHref':
        """Initialize a SecurityGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentityById(SecurityGroupIdentity):
    """
    SecurityGroupIdentityById.

    :attr str id: The unique identifier for this security group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a SecurityGroupIdentityById object.

        :param str id: The unique identifier for this security group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupIdentityById':
        """Initialize a SecurityGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemoteCIDR(SecurityGroupRulePatchRemote):
    """
    SecurityGroupRulePatchRemoteCIDR.

    :attr str cidr_block: The CIDR block. This property may add support for IPv6
          CIDR blocks in the future. When processing a value in this property, verify that
          the CIDR block is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected CIDR block format was encountered.
    """

    def __init__(self, cidr_block: str) -> None:
        """
        Initialize a SecurityGroupRulePatchRemoteCIDR object.

        :param str cidr_block: The CIDR block. This property may add support for
               IPv6 CIDR blocks in the future. When processing a value in this property,
               verify that the CIDR block is in an expected format. If it is not, log an
               error. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected CIDR block format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePatchRemoteCIDR':
        """Initialize a SecurityGroupRulePatchRemoteCIDR object from a json dictionary."""
        args = {}
        if 'cidr_block' in _dict:
            args['cidr_block'] = _dict.get('cidr_block')
        else:
            raise ValueError(
                'Required property \'cidr_block\' not present in SecurityGroupRulePatchRemoteCIDR JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatchRemoteCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidr_block') and self.cidr_block is not None:
            _dict['cidr_block'] = self.cidr_block
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePatchRemoteCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePatchRemoteCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePatchRemoteCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemoteIP(SecurityGroupRulePatchRemote):
    """
    SecurityGroupRulePatchRemoteIP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a SecurityGroupRulePatchRemoteIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePatchRemoteIP':
        """Initialize a SecurityGroupRulePatchRemoteIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in SecurityGroupRulePatchRemoteIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatchRemoteIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePatchRemoteIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePatchRemoteIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePatchRemoteIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemoteSecurityGroupIdentity(
        SecurityGroupRulePatchRemote):
    """
    Identifies a security group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById',
                'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN',
                'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref'
            ]))
        raise Exception(msg)


class SecurityGroupRulePrototypeRemoteCIDR(SecurityGroupRulePrototypeRemote):
    """
    SecurityGroupRulePrototypeRemoteCIDR.

    :attr str cidr_block: The CIDR block. This property may add support for IPv6
          CIDR blocks in the future. When processing a value in this property, verify that
          the CIDR block is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected CIDR block format was encountered.
    """

    def __init__(self, cidr_block: str) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemoteCIDR object.

        :param str cidr_block: The CIDR block. This property may add support for
               IPv6 CIDR blocks in the future. When processing a value in this property,
               verify that the CIDR block is in an expected format. If it is not, log an
               error. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected CIDR block format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePrototypeRemoteCIDR':
        """Initialize a SecurityGroupRulePrototypeRemoteCIDR object from a json dictionary."""
        args = {}
        if 'cidr_block' in _dict:
            args['cidr_block'] = _dict.get('cidr_block')
        else:
            raise ValueError(
                'Required property \'cidr_block\' not present in SecurityGroupRulePrototypeRemoteCIDR JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeRemoteCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidr_block') and self.cidr_block is not None:
            _dict['cidr_block'] = self.cidr_block
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeRemoteCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePrototypeRemoteCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePrototypeRemoteCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePrototypeRemoteIP(SecurityGroupRulePrototypeRemote):
    """
    SecurityGroupRulePrototypeRemoteIP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemoteIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePrototypeRemoteIP':
        """Initialize a SecurityGroupRulePrototypeRemoteIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in SecurityGroupRulePrototypeRemoteIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeRemoteIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeRemoteIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePrototypeRemoteIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePrototypeRemoteIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePrototypeRemoteSecurityGroupIdentity(
        SecurityGroupRulePrototypeRemote):
    """
    Identifies a security group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById',
                'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN',
                'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref'
            ]))
        raise Exception(msg)


class SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll(
        SecurityGroupRulePrototype):
    """
    When `protocol` is `all`, then it's invalid to specify `port_min`, `port_max`, `type`
    or
    `code`.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses or
          security groups from which this rule will allow traffic (or to
          which, for outbound rules). Can be specified as an IP address, a CIDR block, or
          a
          security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to allow
          traffic
          from any source (or to any source, for outbound rules).
    """

    def __init__(self,
                 direction: str,
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 remote: 'SecurityGroupRulePrototypeRemote' = None) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        :param SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses
               or security groups from which this rule will allow traffic (or to
               which, for outbound rules). Can be specified as an IP address, a CIDR
               block, or a
               security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to
               allow traffic
               from any source (or to any source, for outbound rules).
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll':
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP(
        SecurityGroupRulePrototype):
    """
    When `protocol` is `icmp`, then the rule may also contain fields to specify an ICMP
    `type` and `code`. Field `code` may only be specified if `type` is also specified. If
    type is not specified, then traffic is allowed for all types and codes. If type is
    specified and code is not specified, then traffic is allowed with the specified type
    for all codes.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses or
          security groups from which this rule will allow traffic (or to
          which, for outbound rules). Can be specified as an IP address, a CIDR block, or
          a
          security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to allow
          traffic
          from any source (or to any source, for outbound rules).
    :attr int code: (optional) The ICMP traffic code to allow.
    :attr int type: (optional) The ICMP traffic type to allow.
    """

    def __init__(self,
                 direction: str,
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 remote: 'SecurityGroupRulePrototypeRemote' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        :param SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses
               or security groups from which this rule will allow traffic (or to
               which, for outbound rules). Can be specified as an IP address, a CIDR
               block, or a
               security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to
               allow traffic
               from any source (or to any source, for outbound rules).
        :param int code: (optional) The ICMP traffic code to allow.
        :param int type: (optional) The ICMP traffic type to allow.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote
        self.code = code
        self.type = type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP':
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP(
        SecurityGroupRulePrototype):
    """
    If `protocol` is either `tcp` or `udp`, then the rule may also contain `port_min` and
    `port_max`. Either both should be set, or neither. When neither is set then traffic is
    allowed on all ports. For a single port, set both to the same value.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses or
          security groups from which this rule will allow traffic (or to
          which, for outbound rules). Can be specified as an IP address, a CIDR block, or
          a
          security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to allow
          traffic
          from any source (or to any source, for outbound rules).
    :attr int port_max: (optional) The inclusive upper bound of TCP/UDP port range.
    :attr int port_min: (optional) The inclusive lower bound of TCP/UDP port range.
    """

    def __init__(self,
                 direction: str,
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 remote: 'SecurityGroupRulePrototypeRemote' = None,
                 port_max: int = None,
                 port_min: int = None) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        :param SecurityGroupRulePrototypeRemote remote: (optional) The IP addresses
               or security groups from which this rule will allow traffic (or to
               which, for outbound rules). Can be specified as an IP address, a CIDR
               block, or a
               security group. If omitted, a CIDR block of `0.0.0.0/0` will be used to
               allow traffic
               from any source (or to any source, for outbound rules).
        :param int port_max: (optional) The inclusive upper bound of TCP/UDP port
               range.
        :param int port_min: (optional) The inclusive lower bound of TCP/UDP port
               range.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote
        self.port_max = port_max
        self.port_min = port_min

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP':
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'port_max' in _dict:
            args['port_max'] = _dict.get('port_max')
        if 'port_min' in _dict:
            args['port_min'] = _dict.get('port_min')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'port_max') and self.port_max is not None:
            _dict['port_max'] = self.port_max
        if hasattr(self, 'port_min') and self.port_min is not None:
            _dict['port_min'] = self.port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRuleRemoteCIDR(SecurityGroupRuleRemote):
    """
    SecurityGroupRuleRemoteCIDR.

    :attr str cidr_block: The CIDR block. This property may add support for IPv6
          CIDR blocks in the future. When processing a value in this property, verify that
          the CIDR block is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected CIDR block format was encountered.
    """

    def __init__(self, cidr_block: str) -> None:
        """
        Initialize a SecurityGroupRuleRemoteCIDR object.

        :param str cidr_block: The CIDR block. This property may add support for
               IPv6 CIDR blocks in the future. When processing a value in this property,
               verify that the CIDR block is in an expected format. If it is not, log an
               error. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected CIDR block format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemoteCIDR':
        """Initialize a SecurityGroupRuleRemoteCIDR object from a json dictionary."""
        args = {}
        if 'cidr_block' in _dict:
            args['cidr_block'] = _dict.get('cidr_block')
        else:
            raise ValueError(
                'Required property \'cidr_block\' not present in SecurityGroupRuleRemoteCIDR JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemoteCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidr_block') and self.cidr_block is not None:
            _dict['cidr_block'] = self.cidr_block
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemoteCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemoteCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemoteCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemoteIP(SecurityGroupRuleRemote):
    """
    SecurityGroupRuleRemoteIP.

    :attr str address: The IP address. This property may add support for IPv6
          addresses in the future. When processing a value in this property, verify that
          the address is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected IP address format was encountered.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a SecurityGroupRuleRemoteIP object.

        :param str address: The IP address. This property may add support for IPv6
               addresses in the future. When processing a value in this property, verify
               that the address is in an expected format. If it is not, log an error.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected IP address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemoteIP':
        """Initialize a SecurityGroupRuleRemoteIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in SecurityGroupRuleRemoteIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemoteIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemoteIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemoteIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemoteIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemoteSecurityGroupReference(SecurityGroupRuleRemote):
    """
    SecurityGroupRuleRemoteSecurityGroupReference.

    :attr str id: The unique identifier for this security group.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str name: The user-defined name for this security group. Names must be
          unique within the VPC the security group resides in.
    """

    def __init__(self, id: str, crn: str, href: str, name: str) -> None:
        """
        Initialize a SecurityGroupRuleRemoteSecurityGroupReference object.

        :param str id: The unique identifier for this security group.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str name: The user-defined name for this security group. Names must
               be unique within the VPC the security group resides in.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleRemoteSecurityGroupReference':
        """Initialize a SecurityGroupRuleRemoteSecurityGroupReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemoteSecurityGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemoteSecurityGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'SecurityGroupRuleRemoteSecurityGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'SecurityGroupRuleRemoteSecurityGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleSecurityGroupRuleProtocolAll(SecurityGroupRule):
    """
    When `protocol` is `all`, then it's invalid to specify `port_min`, `port_max`, `type`
    or
    `code`.

    :attr str id: The unique identifier for this security group rule.
    :attr str href: The URL for this security group rule.
    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRuleRemote remote: The IP addresses or security groups from
          which this rule allows traffic (or to which,
          for outbound rules). Can be specified as an IP address, a CIDR block, or a
          security
          group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to any
          source,
          for outbound rules).
    """

    def __init__(self,
                 id: str,
                 href: str,
                 direction: str,
                 remote: 'SecurityGroupRuleRemote',
                 *,
                 ip_version: str = None,
                 protocol: str = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object.

        :param str id: The unique identifier for this security group rule.
        :param str href: The URL for this security group rule.
        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param SecurityGroupRuleRemote remote: The IP addresses or security groups
               from which this rule allows traffic (or to which,
               for outbound rules). Can be specified as an IP address, a CIDR block, or a
               security
               group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to
               any source,
               for outbound rules).
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolAll':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError(
                'Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleSecurityGroupRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'SecurityGroupRuleSecurityGroupRuleProtocolAll') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'SecurityGroupRuleSecurityGroupRuleProtocolAll') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRuleSecurityGroupRuleProtocolICMP(SecurityGroupRule):
    """
    When `protocol` is `icmp`, then the rule may also contain fields to specify an ICMP
    `type` and `code`. Field `code` may only be specified if `type` is also specified. If
    type is not specified, then traffic is allowed for all types and codes. If type is
    specified and code is not specified, then traffic is allowed with the specified type
    for all codes.

    :attr str id: The unique identifier for this security group rule.
    :attr str href: The URL for this security group rule.
    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRuleRemote remote: The IP addresses or security groups from
          which this rule allows traffic (or to which,
          for outbound rules). Can be specified as an IP address, a CIDR block, or a
          security
          group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to any
          source,
          for outbound rules).
    :attr int code: (optional) The ICMP traffic code to allow.
    :attr int type: (optional) The ICMP traffic type to allow.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 direction: str,
                 remote: 'SecurityGroupRuleRemote',
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object.

        :param str id: The unique identifier for this security group rule.
        :param str href: The URL for this security group rule.
        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param SecurityGroupRuleRemote remote: The IP addresses or security groups
               from which this rule allows traffic (or to which,
               for outbound rules). Can be specified as an IP address, a CIDR block, or a
               security
               group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to
               any source,
               for outbound rules).
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        :param int code: (optional) The ICMP traffic code to allow.
        :param int type: (optional) The ICMP traffic type to allow.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote
        self.code = code
        self.type = type

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolICMP':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError(
                'Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON'
            )
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleSecurityGroupRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'SecurityGroupRuleSecurityGroupRuleProtocolICMP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'SecurityGroupRuleSecurityGroupRuleProtocolICMP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP(SecurityGroupRule):
    """
    If `protocol` is either `tcp` or `udp`, then the rule may also contain `port_min` and
    `port_max`. Either both should be set, or neither. When neither is set then traffic is
    allowed on all ports. For a single port, set both to the same value.

    :attr str id: The unique identifier for this security group rule.
    :attr str href: The URL for this security group rule.
    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr str protocol: (optional) The protocol to enforce.
    :attr SecurityGroupRuleRemote remote: The IP addresses or security groups from
          which this rule allows traffic (or to which,
          for outbound rules). Can be specified as an IP address, a CIDR block, or a
          security
          group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to any
          source,
          for outbound rules).
    :attr int port_max: (optional) The inclusive upper bound of TCP/UDP port range.
    :attr int port_min: (optional) The inclusive lower bound of TCP/UDP port range.
    """

    def __init__(self,
                 id: str,
                 href: str,
                 direction: str,
                 remote: 'SecurityGroupRuleRemote',
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 port_max: int = None,
                 port_min: int = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object.

        :param str id: The unique identifier for this security group rule.
        :param str href: The URL for this security group rule.
        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param SecurityGroupRuleRemote remote: The IP addresses or security groups
               from which this rule allows traffic (or to which,
               for outbound rules). Can be specified as an IP address, a CIDR block, or a
               security
               group. A CIDR block of `0.0.0.0/0` allows traffic from any source (or to
               any source,
               for outbound rules).
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this field, if they are
               used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param str protocol: (optional) The protocol to enforce.
        :param int port_max: (optional) The inclusive upper bound of TCP/UDP port
               range.
        :param int port_min: (optional) The inclusive lower bound of TCP/UDP port
               range.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.href = href
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote
        self.port_max = port_max
        self.port_min = port_min

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON'
            )
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError(
                'Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON'
            )
        if 'port_max' in _dict:
            args['port_max'] = _dict.get('port_max')
        if 'port_min' in _dict:
            args['port_min'] = _dict.get('port_min')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'port_max') and self.port_max is not None:
            _dict['port_max'] = self.port_max
        if hasattr(self, 'port_min') and self.port_min is not None:
            _dict['port_min'] = self.port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce, either `inbound` or `outbound`.
        """
        INBOUND = 'inbound'
        OUTBOUND = 'outbound'

    class IpVersionEnum(str, Enum):
        """
        The IP version to enforce. The format of `remote.address` or `remote.cidr_block`
        must match this field, if they are used. Alternatively, if `remote` references a
        security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """
        IPV4 = 'ipv4'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'


class SubnetIdentityByCRN(SubnetIdentity):
    """
    SubnetIdentityByCRN.

    :attr str crn: The CRN for this subnet.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a SubnetIdentityByCRN object.

        :param str crn: The CRN for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetIdentityByCRN':
        """Initialize a SubnetIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SubnetIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetIdentityByHref(SubnetIdentity):
    """
    SubnetIdentityByHref.

    :attr str href: The URL for this subnet.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SubnetIdentityByHref object.

        :param str href: The URL for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetIdentityByHref':
        """Initialize a SubnetIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SubnetIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetIdentityById(SubnetIdentity):
    """
    SubnetIdentityById.

    :attr str id: The unique identifier for this subnet.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a SubnetIdentityById object.

        :param str id: The unique identifier for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetIdentityById':
        """Initialize a SubnetIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SubnetIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetPrototypeSubnetByCIDR(SubnetPrototype):
    """
    SubnetPrototypeSubnetByCIDR.

    :attr str name: (optional) The user-defined name for this subnet. Names must be
          unique within the VPC the subnet resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr NetworkACLIdentity network_acl: (optional) The network ACL to use for this
          subnet.
    :attr PublicGatewayIdentity public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr VPCIdentity vpc: The VPC the subnet is to be a part of.
    :attr str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
          format. The prefix length of the subnet's CIDR must be between `/8` (16,777,216
          addresses) and `/29` (8 addresses). The IPv4 range of the subnet's CIDR must
          fall within an existing address prefix in the VPC. The subnet will be created in
          the zone of the address prefix that contains the IPv4 CIDR. If zone is
          specified, it must match the zone of the address prefix that contains the
          subnet's IPv4 CIDR.
    :attr ZoneIdentity zone: (optional) The zone the subnet is to reside in.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 ipv4_cidr_block: str,
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 ip_version: str = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 zone: 'ZoneIdentity' = None) -> None:
        """
        Initialize a SubnetPrototypeSubnetByCIDR object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
               format. The prefix length of the subnet's CIDR must be between `/8`
               (16,777,216 addresses) and `/29` (8 addresses). The IPv4 range of the
               subnet's CIDR must fall within an existing address prefix in the VPC. The
               subnet will be created in the zone of the address prefix that contains the
               IPv4 CIDR. If zone is specified, it must match the zone of the address
               prefix that contains the subnet's IPv4 CIDR.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param ZoneIdentity zone: (optional) The zone the subnet is to reside in.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.ip_version = ip_version
        self.resource_group = resource_group
        self.vpc = vpc
        self.ipv4_cidr_block = ipv4_cidr_block
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetPrototypeSubnetByCIDR':
        """Initialize a SubnetPrototypeSubnetByCIDR object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_acl' in _dict:
            args['network_acl'] = _dict.get('network_acl')
        if 'public_gateway' in _dict:
            args['public_gateway'] = _dict.get('public_gateway')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError(
                'Required property \'vpc\' not present in SubnetPrototypeSubnetByCIDR JSON'
            )
        if 'ipv4_cidr_block' in _dict:
            args['ipv4_cidr_block'] = _dict.get('ipv4_cidr_block')
        else:
            raise ValueError(
                'Required property \'ipv4_cidr_block\' not present in SubnetPrototypeSubnetByCIDR JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPrototypeSubnetByCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self,
                   'ipv4_cidr_block') and self.ipv4_cidr_block is not None:
            _dict['ipv4_cidr_block'] = self.ipv4_cidr_block
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetPrototypeSubnetByCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPrototypeSubnetByCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPrototypeSubnetByCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this subnet.
        """
        IPV4 = 'ipv4'


class SubnetPrototypeSubnetByTotalCount(SubnetPrototype):
    """
    SubnetPrototypeSubnetByTotalCount.

    :attr str name: (optional) The user-defined name for this subnet. Names must be
          unique within the VPC the subnet resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr NetworkACLIdentity network_acl: (optional) The network ACL to use for this
          subnet.
    :attr PublicGatewayIdentity public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr VPCIdentity vpc: The VPC the subnet is to be a part of.
    :attr int total_ipv4_address_count: The total number of IPv4 addresses required.
          Must be a power of 2. The VPC must have a default address prefix in the
          specified zone, and that prefix must have a free CIDR range with at least this
          number of addresses.
    :attr ZoneIdentity zone: The zone the subnet is to reside in.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 total_ipv4_address_count: int,
                 zone: 'ZoneIdentity',
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 ip_version: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a SubnetPrototypeSubnetByTotalCount object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param int total_ipv4_address_count: The total number of IPv4 addresses
               required. Must be a power of 2. The VPC must have a default address prefix
               in the specified zone, and that prefix must have a free CIDR range with at
               least this number of addresses.
        :param ZoneIdentity zone: The zone the subnet is to reside in.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.ip_version = ip_version
        self.resource_group = resource_group
        self.vpc = vpc
        self.total_ipv4_address_count = total_ipv4_address_count
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetPrototypeSubnetByTotalCount':
        """Initialize a SubnetPrototypeSubnetByTotalCount object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_acl' in _dict:
            args['network_acl'] = _dict.get('network_acl')
        if 'public_gateway' in _dict:
            args['public_gateway'] = _dict.get('public_gateway')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError(
                'Required property \'vpc\' not present in SubnetPrototypeSubnetByTotalCount JSON'
            )
        if 'total_ipv4_address_count' in _dict:
            args['total_ipv4_address_count'] = _dict.get(
                'total_ipv4_address_count')
        else:
            raise ValueError(
                'Required property \'total_ipv4_address_count\' not present in SubnetPrototypeSubnetByTotalCount JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in SubnetPrototypeSubnetByTotalCount JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPrototypeSubnetByTotalCount object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'total_ipv4_address_count'
                  ) and self.total_ipv4_address_count is not None:
            _dict['total_ipv4_address_count'] = self.total_ipv4_address_count
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetPrototypeSubnetByTotalCount object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPrototypeSubnetByTotalCount') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPrototypeSubnetByTotalCount') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this subnet.
        """
        IPV4 = 'ipv4'


class VPCIdentityByCRN(VPCIdentity):
    """
    VPCIdentityByCRN.

    :attr str crn: The CRN for this VPC.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a VPCIdentityByCRN object.

        :param str crn: The CRN for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCIdentityByCRN':
        """Initialize a VPCIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPCIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCIdentityByHref(VPCIdentity):
    """
    VPCIdentityByHref.

    :attr str href: The URL for this VPC.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPCIdentityByHref object.

        :param str href: The URL for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCIdentityByHref':
        """Initialize a VPCIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPCIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCIdentityById(VPCIdentity):
    """
    VPCIdentityById.

    :attr str id: The unique identifier for this VPC.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a VPCIdentityById object.

        :param str id: The unique identifier for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCIdentityById':
        """Initialize a VPCIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPCIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentity(
        VolumeAttachmentPrototypeInstanceContextVolume):
    """
    Identifies a volume by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById',
                'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN',
                'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref'
            ]))
        raise Exception(msg)


class VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContext(
        VolumeAttachmentPrototypeInstanceContextVolume):
    """
    VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContext.

    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 *,
                 name: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContext object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param str name: (optional) The unique user-defined name for this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity'
            ]))
        raise Exception(msg)


class VolumeIdentityByCRN(VolumeIdentity):
    """
    VolumeIdentityByCRN.

    :attr str crn: The CRN for this volume.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a VolumeIdentityByCRN object.

        :param str crn: The CRN for this volume.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeIdentityByCRN':
        """Initialize a VolumeIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VolumeIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeIdentityByHref(VolumeIdentity):
    """
    VolumeIdentityByHref.

    :attr str href: The URL for this volume.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeIdentityByHref object.

        :param str href: The URL for this volume.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeIdentityByHref':
        """Initialize a VolumeIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeIdentityById(VolumeIdentity):
    """
    VolumeIdentityById.

    :attr str id: The unique identifier for this volume.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a VolumeIdentityById object.

        :param str id: The unique identifier for this volume.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeIdentityById':
        """Initialize a VolumeIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileIdentityByHref(VolumeProfileIdentity):
    """
    VolumeProfileIdentityByHref.

    :attr str href: The URL for this volume profile.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeProfileIdentityByHref object.

        :param str href: The URL for this volume profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileIdentityByHref':
        """Initialize a VolumeProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfileIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileIdentityByName(VolumeProfileIdentity):
    """
    VolumeProfileIdentityByName.

    :attr str name: The name for this volume profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a VolumeProfileIdentityByName object.

        :param str name: The name for this volume profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileIdentityByName':
        """Initialize a VolumeProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeProfileIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumePrototypeVolumeByCapacity(VolumePrototype):
    """
    VolumePrototypeVolumeByCapacity.

    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :attr ZoneIdentity zone: The location of the volume.
    :attr int capacity: The capacity of the volume in gigabytes. Note that the
          specified minimum and maximum capacity values for creating or updating volumes
          may expand in the future.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 zone: 'ZoneIdentity',
                 capacity: int,
                 *,
                 name: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a VolumePrototypeVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param ZoneIdentity zone: The location of the volume.
        :param int capacity: The capacity of the volume in gigabytes. Note that the
               specified minimum and maximum capacity values for creating or updating
               volumes may expand in the future.
        :param str name: (optional) The unique user-defined name for this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.profile = profile
        self.encryption_key = encryption_key
        self.iops = iops
        self.resource_group = resource_group
        self.zone = zone
        self.capacity = capacity

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeVolumeByCapacity':
        """Initialize a VolumePrototypeVolumeByCapacity object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError(
                'Required property \'profile\' not present in VolumePrototypeVolumeByCapacity JSON'
            )
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in VolumePrototypeVolumeByCapacity JSON'
            )
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError(
                'Required property \'capacity\' not present in VolumePrototypeVolumeByCapacity JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumePrototypeVolumeByCapacity object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumePrototypeVolumeByCapacity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumePrototypeVolumeByCapacity') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumePrototypeVolumeByCapacity') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ZoneIdentityByHref(ZoneIdentity):
    """
    ZoneIdentityByHref.

    :attr str href: The URL for this zone.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ZoneIdentityByHref object.

        :param str href: The URL for this zone.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ZoneIdentityByHref':
        """Initialize a ZoneIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ZoneIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ZoneIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ZoneIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ZoneIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ZoneIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ZoneIdentityByName(ZoneIdentity):
    """
    ZoneIdentityByName.

    :attr str name: The name for this zone.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a ZoneIdentityByName object.

        :param str name: The name for this zone.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ZoneIdentityByName':
        """Initialize a ZoneIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ZoneIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ZoneIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ZoneIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ZoneIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ZoneIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN(
        FlowLogCollectorPrototypeTargetInstanceIdentity):
    """
    FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN.

    :attr str crn: The CRN for this virtual server instance.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN object.

        :param str crn: The CRN for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN':
        """Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref(
        FlowLogCollectorPrototypeTargetInstanceIdentity):
    """
    FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref.

    :attr str href: The URL for this virtual server instance.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref object.

        :param str href: The URL for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref':
        """Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById(
        FlowLogCollectorPrototypeTargetInstanceIdentity):
    """
    FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById.

    :attr str id: The unique identifier for this virtual server instance.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById object.

        :param str id: The unique identifier for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById':
        """Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorPrototypeTargetInstanceIdentityInstanceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(
        FlowLogCollectorPrototypeTargetNetworkInterfaceIdentity):
    """
    FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this network interface.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById(
        FlowLogCollectorPrototypeTargetNetworkInterfaceIdentity):
    """
    FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this network interface.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorPrototypeTargetNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN(
        FlowLogCollectorPrototypeTargetSubnetIdentity):
    """
    FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN.

    :attr str crn: The CRN for this subnet.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN object.

        :param str crn: The CRN for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN':
        """Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref(
        FlowLogCollectorPrototypeTargetSubnetIdentity):
    """
    FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref.

    :attr str href: The URL for this subnet.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref object.

        :param str href: The URL for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref':
        """Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById(
        FlowLogCollectorPrototypeTargetSubnetIdentity):
    """
    FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById.

    :attr str id: The unique identifier for this subnet.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById object.

        :param str id: The unique identifier for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById':
        """Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorPrototypeTargetSubnetIdentitySubnetIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN(
        FlowLogCollectorPrototypeTargetVPCIdentity):
    """
    FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN.

    :attr str crn: The CRN for this VPC.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN object.

        :param str crn: The CRN for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN':
        """Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref(
        FlowLogCollectorPrototypeTargetVPCIdentity):
    """
    FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref.

    :attr str href: The URL for this VPC.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref object.

        :param str href: The URL for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref':
        """Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById(
        FlowLogCollectorPrototypeTargetVPCIdentity):
    """
    FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById.

    :attr str id: The unique identifier for this VPC.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById object.

        :param str id: The unique identifier for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById':
        """Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'FlowLogCollectorPrototypeTargetVPCIdentityVPCIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(
        LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The pool's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(
        LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object.

        :param str id: The unique identifier for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyPatchTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(
        LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The pool's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(
        LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object.

        :param str id: The unique identifier for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyPrototypeTargetLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN(
        LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN.

    :attr str crn: The CRN for this virtual server instance.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object.

        :param str crn: The CRN for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref(
        LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref.

    :attr str href: The URL for this virtual server instance.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object.

        :param str href: The URL for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById(
        LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById.

    :attr str id: The unique identifier for this virtual server instance.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object.

        :param str id: The unique identifier for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress(
        PublicGatewayPrototypeFloatingIpFloatingIPIdentity):
    """
    PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress.

    :attr str address: The globally unique IP address.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress object.

        :param str address: The globally unique IP address.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress':
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByAddress'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN(
        PublicGatewayPrototypeFloatingIpFloatingIPIdentity):
    """
    PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN.

    :attr str crn: The CRN for this floating IP.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN object.

        :param str crn: The CRN for this floating IP.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN':
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref(
        PublicGatewayPrototypeFloatingIpFloatingIPIdentity):
    """
    PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref.

    :attr str href: The URL for this floating IP.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref object.

        :param str href: The URL for this floating IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref':
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById(
        PublicGatewayPrototypeFloatingIpFloatingIPIdentity):
    """
    PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById.

    :attr str id: The unique identifier for this floating IP.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById object.

        :param str id: The unique identifier for this floating IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById':
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayPrototypeFloatingIpFloatingIPIdentityFloatingIPIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN(
        SecurityGroupRulePatchRemoteSecurityGroupIdentity):
    """
    SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN.

    :attr str crn: The security group's CRN.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object.

        :param str crn: The security group's CRN.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN':
        """Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref(
        SecurityGroupRulePatchRemoteSecurityGroupIdentity):
    """
    SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref.

    :attr str href: The security group's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object.

        :param str href: The security group's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref':
        """Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById(
        SecurityGroupRulePatchRemoteSecurityGroupIdentity):
    """
    SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById.

    :attr str id: The unique identifier for this security group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById object.

        :param str id: The unique identifier for this security group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById':
        """Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRulePatchRemoteSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN(
        SecurityGroupRulePrototypeRemoteSecurityGroupIdentity):
    """
    SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN.

    :attr str crn: The security group's CRN.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object.

        :param str crn: The security group's CRN.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN':
        """Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref(
        SecurityGroupRulePrototypeRemoteSecurityGroupIdentity):
    """
    SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref.

    :attr str href: The security group's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object.

        :param str href: The security group's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref':
        """Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById(
        SecurityGroupRulePrototypeRemoteSecurityGroupIdentity):
    """
    SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById.

    :attr str id: The unique identifier for this security group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById object.

        :param str id: The unique identifier for this security group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById':
        """Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRulePrototypeRemoteSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN(
        VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentity):
    """
    VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN.

    :attr str crn: The CRN for this volume.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN object.

        :param str crn: The CRN for this volume.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN':
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref(
        VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentity):
    """
    VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref.

    :attr str href: The URL for this volume.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref object.

        :param str href: The URL for this volume.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref':
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById(
        VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentity):
    """
    VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById.

    :attr str id: The unique identifier for this volume.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById object.

        :param str id: The unique identifier for this volume.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById':
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumeIdentityVolumeIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity(
        VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContext
):
    """
    VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity.

    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr int capacity: The capacity of the volume in gigabytes. Note that the
          specified minimum and maximum capacity values for creating or updating volumes
          may expand in the future.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 capacity: int,
                 *,
                 name: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param int capacity: The capacity of the volume in gigabytes. Note that the
               specified minimum and maximum capacity values for creating or updating
               volumes may expand in the future.
        :param str name: (optional) The unique user-defined name for this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.profile = profile
        self.encryption_key = encryption_key
        self.iops = iops
        self.capacity = capacity

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity':
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError(
                'Required property \'profile\' not present in VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON'
            )
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError(
                'Required property \'capacity\' not present in VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentPrototypeInstanceContextVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other
