# coding: utf-8

# (C) Copyright IBM Corp. 2021.
#
# 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.31.0-902c9336-20210504-161156
"""
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 = '2021-05-06',
        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.
        """
        if version is None:
            raise ValueError('version must be provided')

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

    def __init__(
        self,
        version: str = '2021-05-06',
        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.
        """
        if version is None:
            raise ValueError('version must be provided')

        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 in the region. 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,
                   *,
                   address_prefix_management: str = None,
                   classic_access: bool = None,
                   name: str = 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 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 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 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 = {
            'address_prefix_management': address_prefix_management,
            'classic_access': classic_access,
            '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 = '/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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpc(self, id: str, vpc_patch: 'VPCPatch',
                   **kwargs) -> DetailedResponse:
        """
        Update a VPC.

        This request updates a VPC's name.

        :param str id: The VPC identifier.
        :param VPCPatch vpc_patch: The VPC patch.
        :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')
        if vpc_patch is None:
            raise ValueError('vpc_patch must be provided')
        if isinstance(vpc_patch, VPCPatch):
            vpc_patch = convert_model(vpc_patch)
        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 = json.dumps(vpc_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{id}'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{id}/default_network_acl'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc_default_routing_table(self, id: str,
                                      **kwargs) -> DetailedResponse:
        """
        Retrieve a VPC's default routing table.

        This request retrieves the default routing table for the VPC specified by the
        identifier in the URL. The default routing table is associated with any subnets in
        the VPC which have not been explicitly associated with a user-defined routing
        table.

        :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 `DefaultRoutingTable` 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_routing_table')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{id}/default_routing_table'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{id}/default_security_group'.format(**path_param_dict)
        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 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'

        path_param_keys = ['vpc_id']
        path_param_values = self.encode_path_vars(vpc_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/address_prefixes'.format(**path_param_dict)
        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',
                                  *,
                                  is_default: bool = None,
                                  name: str = None,
                                  **kwargs) -> DetailedResponse:
        """
        Create an address prefix for a VPC.

        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 or any of the following reserved address ranges:
                 - `127.0.0.0/8` (IPv4 loopback addresses)
                 - `161.26.0.0/16` (IBM services)
                 - `166.8.0.0/14` (Cloud Service Endpoints)
                 - `169.254.0.0/16` (IPv4 link-local addresses)
                 - `224.0.0.0/4` (IPv4 multicast addresses)
               The prefix length of the address prefix's CIDR must be between `/9`
               (8,388,608 addresses) and `/29` (8 addresses).
        :param ZoneIdentity zone: The zone this address prefix will reside in.
        :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 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 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,
            'is_default': is_default,
            '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'

        path_param_keys = ['vpc_id']
        path_param_values = self.encode_path_vars(vpc_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/address_prefixes'.format(**path_param_dict)
        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 an address 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'))

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/address_prefixes/{id}'.format(**path_param_dict)
        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 an address 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'

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/address_prefixes/{id}'.format(**path_param_dict)
        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,
                                  address_prefix_patch: 'AddressPrefixPatch',
                                  **kwargs) -> DetailedResponse:
        """
        Update an address 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 AddressPrefixPatch address_prefix_patch: The prefix patch.
        :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')
        if address_prefix_patch is None:
            raise ValueError('address_prefix_patch must be provided')
        if isinstance(address_prefix_patch, AddressPrefixPatch):
            address_prefix_patch = convert_model(address_prefix_patch)
        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 = json.dumps(address_prefix_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/address_prefixes/{id}'.format(**path_param_dict)
        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,
                        start: str = None,
                        limit: int = None,
                        **kwargs) -> DetailedResponse:
        """
        List all routes in a VPC's default routing table.

        This request lists all routes in the VPC's default routing table. 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 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 `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,
            'start': start,
            'limit': limit
        }

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

        path_param_keys = ['vpc_id']
        path_param_values = self.encode_path_vars(vpc_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routes'.format(**path_param_dict)
        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,
                         destination: str,
                         zone: 'ZoneIdentity',
                         *,
                         action: str = None,
                         name: str = None,
                         next_hop: 'RouteNextHopPrototype' = None,
                         **kwargs) -> DetailedResponse:
        """
        Create a route in a 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 str destination: The destination of the route. At most two routes
               per `zone` in a table can have the same destination, and only if both
               routes have an `action` of `deliver` and the
               `next_hop` is an IP address.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str action: (optional) The action to perform with a packet matching
               the route:
               - `delegate`: delegate to the system's built-in routes
               - `delegate_vpc`: delegate to the system's built-in routes, ignoring
               Internet-bound
                 routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to.  For
               other `action` values, it must be omitted or specified as `0.0.0.0`.
        :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 destination is None:
            raise ValueError('destination must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        zone = convert_model(zone)
        if next_hop is not None:
            next_hop = convert_model(next_hop)
        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 = {
            'destination': destination,
            'zone': zone,
            'action': action,
            'name': name,
            'next_hop': next_hop
        }
        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'

        path_param_keys = ['vpc_id']
        path_param_values = self.encode_path_vars(vpc_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routes'.format(**path_param_dict)
        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 a VPC route.

        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'))

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routes/{id}'.format(**path_param_dict)
        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 a VPC route.

        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'

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routes/{id}'.format(**path_param_dict)
        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, route_patch: 'RoutePatch',
                         **kwargs) -> DetailedResponse:
        """
        Update a VPC route.

        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 RoutePatch route_patch: The route patch.
        :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')
        if route_patch is None:
            raise ValueError('route_patch must be provided')
        if isinstance(route_patch, RoutePatch):
            route_patch = convert_model(route_patch)
        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 = json.dumps(route_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routes/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_vpc_routing_tables(self,
                                vpc_id: str,
                                *,
                                start: str = None,
                                limit: int = None,
                                is_default: bool = None,
                                **kwargs) -> DetailedResponse:
        """
        List all routing tables for a VPC.

        This request lists all user-defined routing tables for a VPC.  Each subnet in a
        VPC is associated with a routing table, which controls delivery of packets sent on
        that subnet according to the action of the most specific matching route in the
        table.  If multiple equally-specific routes exist, traffic will be distributed
        across them.  If no routes match, delivery will be controlled by the system's
        built-in routes.

        :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 bool is_default: (optional) If the supplied value is `true`, filters
               the routing table collection to only the default routing table. If the
               supplied value is `false`, filters the routing table collection to exclude
               the default routing table.
        :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 `RoutingTableCollection` 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_routing_tables')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['vpc_id']
        path_param_values = self.encode_path_vars(vpc_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_vpc_routing_table(self,
                                 vpc_id: str,
                                 *,
                                 name: str = None,
                                 route_direct_link_ingress: bool = None,
                                 route_transit_gateway_ingress: bool = None,
                                 route_vpc_zone_ingress: bool = None,
                                 routes: List['RoutePrototype'] = None,
                                 **kwargs) -> DetailedResponse:
        """
        Create a routing table for a VPC.

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

        :param str vpc_id: The VPC identifier.
        :param str name: (optional) The user-defined name for this routing table.
               Names must be unique within the VPC the routing table resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param bool route_direct_link_ingress: (optional) If set to `true`, this
               routing table will be used to route traffic that originates from [Direct
               Link](https://cloud.ibm.com/docs/dl/) to this VPC. For this to succeed, the
               VPC must not already have a routing table with this property set to `true`.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param bool route_transit_gateway_ingress: (optional) If set to `true`,
               this routing table will be used to route traffic that originates from
               [Transit Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this
               VPC. For this to succeed, the VPC must not already have a routing table
               with this property set to `true`.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
               If [Classic
               Access](https://cloud.ibm.com/docs/vpc?topic=vpc-setting-up-access-to-classic-infrastructure)
               is enabled for this VPC, and this property is set to `true`, its incoming
               traffic will also be routed according to this routing table.
        :param bool route_vpc_zone_ingress: (optional) If set to `true`, this
               routing table will be used to route traffic that originates from subnets in
               other zones in this VPC. For this to succeed, the VPC must not already have
               a routing table with this property set to `true`.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param List[RoutePrototype] routes: (optional) Array of route prototype
               objects for routes to create for this routing table. If unspecified, the
               routing table will be created with no routes.
        :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 `RoutingTable` object
        """

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

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

        data = {
            'name': name,
            'route_direct_link_ingress': route_direct_link_ingress,
            'route_transit_gateway_ingress': route_transit_gateway_ingress,
            'route_vpc_zone_ingress': route_vpc_zone_ingress,
            'routes': routes
        }
        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'

        path_param_keys = ['vpc_id']
        path_param_values = self.encode_path_vars(vpc_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables'.format(**path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpc_routing_table(self, vpc_id: str, id: str,
                                 **kwargs) -> DetailedResponse:
        """
        Delete a VPC routing table.

        This request deletes a routing table.  A routing table cannot be deleted if it is
        associated with any subnets in the VPC. Additionally, a VPC's default routing
        table cannot be deleted. This operation cannot be reversed.

        :param str vpc_id: The VPC identifier.
        :param str id: The routing table 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_routing_table')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc_routing_table(self, vpc_id: str, id: str,
                              **kwargs) -> DetailedResponse:
        """
        Retrieve a VPC routing table.

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

        :param str vpc_id: The VPC identifier.
        :param str id: The routing table 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 `RoutingTable` 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_routing_table')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpc_routing_table(self, vpc_id: str, id: str,
                                 routing_table_patch: 'RoutingTablePatch',
                                 **kwargs) -> DetailedResponse:
        """
        Update a VPC routing table.

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

        :param str vpc_id: The VPC identifier.
        :param str id: The routing table identifier.
        :param RoutingTablePatch routing_table_patch: The routing table patch.
        :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 `RoutingTable` object
        """

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

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

        data = json.dumps(routing_table_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['vpc_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_vpc_routing_table_routes(self,
                                      vpc_id: str,
                                      routing_table_id: str,
                                      *,
                                      start: str = None,
                                      limit: int = None,
                                      **kwargs) -> DetailedResponse:
        """
        List all routes in a VPC routing table.

        This request lists all routes in a VPC routing table. If a subnet has been
        associated with this routing table, delivery of packets sent on a subnet is
        performed according to the action of the most specific matching route in the table
        (provided the subnet and route are in the same zone). If multiple equally-specific
        routes exist, traffic will be distributed across them. If no routes match,
        delivery will be controlled by the system's built-in routes.

        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table 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 `RouteCollection` object
        """

        if vpc_id is None:
            raise ValueError('vpc_id must be provided')
        if routing_table_id is None:
            raise ValueError('routing_table_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpc_routing_table_routes')
        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'

        path_param_keys = ['vpc_id', 'routing_table_id']
        path_param_values = self.encode_path_vars(vpc_id, routing_table_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{routing_table_id}/routes'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

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

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

        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table identifier.
        :param str destination: The destination of the route. At most two routes
               per `zone` in a table can have the same destination, and only if both
               routes have an `action` of `deliver` and the
               `next_hop` is an IP address.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str action: (optional) The action to perform with a packet matching
               the route:
               - `delegate`: delegate to the system's built-in routes
               - `delegate_vpc`: delegate to the system's built-in routes, ignoring
               Internet-bound
                 routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to.  For
               other `action` values, it must be omitted or specified as `0.0.0.0`.
        :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 routing_table_id is None:
            raise ValueError('routing_table_id must be provided')
        if destination is None:
            raise ValueError('destination must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        zone = convert_model(zone)
        if next_hop is not None:
            next_hop = convert_model(next_hop)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_vpc_routing_table_route')
        headers.update(sdk_headers)

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

        data = {
            'destination': destination,
            'zone': zone,
            'action': action,
            'name': name,
            'next_hop': next_hop
        }
        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'

        path_param_keys = ['vpc_id', 'routing_table_id']
        path_param_values = self.encode_path_vars(vpc_id, routing_table_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{routing_table_id}/routes'.format(
            **path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_vpc_routing_table_route(self, vpc_id: str, routing_table_id: str,
                                       id: str, **kwargs) -> DetailedResponse:
        """
        Delete a VPC routing table route.

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

        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table identifier.
        :param str id: The VPC routing table 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 routing_table_id is None:
            raise ValueError('routing_table_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_routing_table_route')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['vpc_id', 'routing_table_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, routing_table_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{routing_table_id}/routes/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_vpc_routing_table_route(self, vpc_id: str, routing_table_id: str,
                                    id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a VPC routing table route.

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

        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table identifier.
        :param str id: The VPC routing table 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 routing_table_id is None:
            raise ValueError('routing_table_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_routing_table_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'

        path_param_keys = ['vpc_id', 'routing_table_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, routing_table_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{routing_table_id}/routes/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_vpc_routing_table_route(self, vpc_id: str, routing_table_id: str,
                                       id: str, route_patch: 'RoutePatch',
                                       **kwargs) -> DetailedResponse:
        """
        Update a VPC routing table route.

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

        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table identifier.
        :param str id: The VPC routing table route identifier.
        :param RoutePatch route_patch: The VPC route patch.
        :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 routing_table_id is None:
            raise ValueError('routing_table_id must be provided')
        if id is None:
            raise ValueError('id must be provided')
        if route_patch is None:
            raise ValueError('route_patch must be provided')
        if isinstance(route_patch, RoutePatch):
            route_patch = convert_model(route_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_vpc_routing_table_route')
        headers.update(sdk_headers)

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

        data = json.dumps(route_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['vpc_id', 'routing_table_id', 'id']
        path_param_values = self.encode_path_vars(vpc_id, routing_table_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpcs/{vpc_id}/routing_tables/{routing_table_id}/routes/{id}'.format(
            **path_param_dict)
        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,
                     routing_table_id: str = None,
                     routing_table_name: 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 str routing_table_id: (optional) Filters the collection to subnets
               attached to the routing table with the specified identifier.
        :param str routing_table_name: (optional) Filters the collection to subnets
               attached to the routing table with the 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 `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,
            'routing_table.id': routing_table_id,
            'routing_table.name': routing_table_name
        }

        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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_subnet(self, id: str, subnet_patch: 'SubnetPatch',
                      **kwargs) -> DetailedResponse:
        """
        Update a 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 SubnetPatch subnet_patch: The subnet patch.
        :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 subnet_patch is None:
            raise ValueError('subnet_patch must be provided')
        if isinstance(subnet_patch, SubnetPatch):
            subnet_patch = convert_model(subnet_patch)
        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 = json.dumps(subnet_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/network_acl'.format(**path_param_dict)
        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')
        if isinstance(network_acl_identity, NetworkACLIdentity):
            network_acl_identity = convert_model(network_acl_identity)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/network_acl'.format(**path_param_dict)
        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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/public_gateway'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/public_gateway'.format(**path_param_dict)
        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')
        if isinstance(public_gateway_identity, PublicGatewayIdentity):
            public_gateway_identity = convert_model(public_gateway_identity)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/public_gateway'.format(**path_param_dict)
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def get_subnet_routing_table(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a subnet's attached routing table.

        This request retrieves the routing table 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 `RoutingTable` 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_routing_table')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/routing_table'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def replace_subnet_routing_table(
            self, id: str, routing_table_identity: 'RoutingTableIdentity',
            **kwargs) -> DetailedResponse:
        """
        Attach a routing table to a subnet.

        This request attaches the routing table, specified in the request body, to the
        subnet specified by the subnet identifier in the URL. This replaces the existing
        routing table on the subnet.
        For this request to succeed, the routing table `route_direct_link_ingress`,
        `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` properties must be
        `false`.

        :param str id: The subnet identifier.
        :param RoutingTableIdentity routing_table_identity: The routing table
               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 `RoutingTable` object
        """

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

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

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{id}/routing_table'.format(**path_param_dict)
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_subnet_reserved_ips(self,
                                 subnet_id: str,
                                 *,
                                 start: str = None,
                                 limit: int = None,
                                 sort: str = None,
                                 **kwargs) -> DetailedResponse:
        """
        List all reserved IPs in a subnet.

        This request lists reserved IPs in a subnet that are unbound or bound to an
        endpoint gateway.

        :param str subnet_id: The subnet 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 sort: (optional) Sorts the returned collection by the specified
               field name in ascending order. A `-` may be prepended to the field name to
               sort in descending order. For example, the value
               `-created_at` sorts the collection by the `created_at` field in descending
               order, and the value `name` sorts it by the `name` field in ascending
               order.
        :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 `ReservedIPCollection` object
        """

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

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

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

        path_param_keys = ['subnet_id']
        path_param_values = self.encode_path_vars(subnet_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{subnet_id}/reserved_ips'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_subnet_reserved_ip(self,
                                  subnet_id: str,
                                  *,
                                  auto_delete: bool = None,
                                  name: str = None,
                                  target: 'ReservedIPTargetPrototype' = None,
                                  **kwargs) -> DetailedResponse:
        """
        Reserve an IP in a subnet.

        This request reserves a system-selected IP address in a subnet.

        :param str subnet_id: The subnet identifier.
        :param bool auto_delete: (optional) If set to `true`, this reserved IP will
               be automatically deleted when the target is deleted or when the reserved IP
               is unbound. The value cannot be set to `true` if the reserved IP is
               unbound.
        :param str name: (optional) The user-defined name for this reserved IP. If
               not specified, the name will be a hyphenated list of randomly-selected
               words. Names must be unique within the subnet the reserved IP resides in.
               Names beginning with `ibm-` are reserved for provider-owned resources.
        :param ReservedIPTargetPrototype target: (optional) The target this
               reserved IP is to be bound to.
        :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 `ReservedIP` object
        """

        if subnet_id is None:
            raise ValueError('subnet_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='create_subnet_reserved_ip')
        headers.update(sdk_headers)

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

        data = {'auto_delete': auto_delete, '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'

        path_param_keys = ['subnet_id']
        path_param_values = self.encode_path_vars(subnet_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{subnet_id}/reserved_ips'.format(**path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_subnet_reserved_ip(self, subnet_id: str, id: str,
                                  **kwargs) -> DetailedResponse:
        """
        Release a reserved IP.

        This request releases a reserved IP. This operation cannot be reversed.

        :param str subnet_id: The subnet identifier.
        :param str id: The reserved 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 subnet_id is None:
            raise ValueError('subnet_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_subnet_reserved_ip')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['subnet_id', 'id']
        path_param_values = self.encode_path_vars(subnet_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{subnet_id}/reserved_ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_subnet_reserved_ip(self, subnet_id: str, id: str,
                               **kwargs) -> DetailedResponse:
        """
        Retrieve a reserved IP.

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

        :param str subnet_id: The subnet identifier.
        :param str id: The reserved 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 `ReservedIP` object
        """

        if subnet_id is None:
            raise ValueError('subnet_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_subnet_reserved_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'

        path_param_keys = ['subnet_id', 'id']
        path_param_values = self.encode_path_vars(subnet_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{subnet_id}/reserved_ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_subnet_reserved_ip(self, subnet_id: str, id: str,
                                  reserved_ip_patch: 'ReservedIPPatch',
                                  **kwargs) -> DetailedResponse:
        """
        Update a reserved IP.

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

        :param str subnet_id: The subnet identifier.
        :param str id: The reserved IP identifier.
        :param ReservedIPPatch reserved_ip_patch: The reserved IP patch.
        :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 `ReservedIP` object
        """

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

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

        data = json.dumps(reserved_ip_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['subnet_id', 'id']
        path_param_values = self.encode_path_vars(subnet_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/subnets/{subnet_id}/reserved_ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       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.
        The images will be sorted by their `created_at` property values, with the newest
        first. Images with identical `created_at` values will be secondarily sorted by
        ascending `id` property values.

        :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 an image.

        This request deletes an image. This operation cannot be reversed. A
        system-provided image is not allowed to be deleted. Additionally, an image cannot
        be deleted if it has a
        `status` of `pending`, `tentative`, or `deleting`.

        :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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/images/{id}'.format(**path_param_dict)
        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 an 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/images/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_image(self, id: str, image_patch: 'ImagePatch',
                     **kwargs) -> DetailedResponse:
        """
        Update an 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. A system-provided image is not allowed to be
        updated. An image with a `status` of `deleting` cannot be updated.

        :param str id: The image identifier.
        :param ImagePatch image_patch: The image patch.
        :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')
        if image_patch is None:
            raise ValueError('image_patch must be provided')
        if isinstance(image_patch, ImagePatch):
            image_patch = convert_model(image_patch)
        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 = json.dumps(image_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/images/{id}'.format(**path_param_dict)
        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:
        """
        List all operating systems.

        This request lists all operating systems 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 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:
        """
        Retrieve 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'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/operating_systems/{name}'.format(**path_param_dict)
        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 in the region. 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,
                   resource_group: 'ResourceGroupIdentity' = None,
                   type: str = 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 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 str type: (optional) The crypto-system used by 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 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,
            'resource_group': resource_group,
            '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 = '/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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/keys/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/keys/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_key(self, id: str, key_patch: 'KeyPatch',
                   **kwargs) -> DetailedResponse:
        """
        Update a key.

        This request updates a key's name.

        :param str id: The key identifier.
        :param KeyPatch key_patch: The key patch.
        :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')
        if key_patch is None:
            raise ValueError('key_patch must be provided')
        if isinstance(key_patch, KeyPatch):
            key_patch = convert_model(key_patch)
        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 = json.dumps(key_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/keys/{id}'.format(**path_param_dict)
        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 provisionable instance profiles 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 an 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'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance/profiles/{name}'.format(**path_param_dict)
        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:
        """
        List all instance templates.

        This request lists all instance templates in the region.

        :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 an 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance/templates/{id}'.format(**path_param_dict)
        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 an instance template.

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

        :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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance/templates/{id}'.format(**path_param_dict)
        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, instance_template_patch: 'InstanceTemplatePatch',
            **kwargs) -> DetailedResponse:
        """
        Update an 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 InstanceTemplatePatch instance_template_patch: The instance template
               patch.
        :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')
        if instance_template_patch is None:
            raise ValueError('instance_template_patch must be provided')
        if isinstance(instance_template_patch, InstanceTemplatePatch):
            instance_template_patch = convert_model(instance_template_patch)
        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 = json.dumps(instance_template_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance/templates/{id}'.format(**path_param_dict)
        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 an 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{id}'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance(self, id: str, instance_patch: 'InstancePatch',
                        **kwargs) -> DetailedResponse:
        """
        Update an 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 InstancePatch instance_patch: The instance patch.
        :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')
        if instance_patch is None:
            raise ValueError('instance_patch must be provided')
        if isinstance(instance_patch, InstancePatch):
            instance_patch = convert_model(instance_patch)
        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 = json.dumps(instance_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{id}'.format(**path_param_dict)
        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 initialization configuration for an 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{id}/initialization'.format(**path_param_dict)
        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'

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/actions'.format(**path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def create_instance_console_access_token(self,
                                             instance_id: str,
                                             console_type: str,
                                             *,
                                             force: bool = None,
                                             **kwargs) -> DetailedResponse:
        """
        Create a console access token for an instance.

        This request creates a new single-use console access token for an instance. All
        console configuration is provided at token create time, and the token is
        subsequently used in the `access_token` query parameter for the WebSocket request.
         The access token is only valid for a short period of time, and a maximum of one
        token is valid for a given instance at a time.

        :param str instance_id: The instance identifier.
        :param str console_type: The instance console type for which this token may
               be used.
        :param bool force: (optional) Indicates whether to disconnect an existing
               serial console session as the serial console cannot be shared.  This has no
               effect on VNC consoles.
        :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 `InstanceConsoleAccessToken` object
        """

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

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

        data = {'console_type': console_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'

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/console_access_token'.format(
            **path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

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

        This request lists all disks on an instance.  A disk is a block device that is
        locally attached to the instance's physical host and is also referred to as
        instance storage. By default, the listed disks are sorted by their `created_at`
        property values, with the newest disk first.

        :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 `InstanceDiskCollection` 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_disks')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/disks'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

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

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

        :param str instance_id: The instance identifier.
        :param str id: The instance disk 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 `InstanceDisk` 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_disk')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/disks/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_disk(self, instance_id: str, id: str,
                             instance_disk_patch: 'InstanceDiskPatch',
                             **kwargs) -> DetailedResponse:
        """
        Update an instance disk.

        This request updates the instance disk with the information in a provided patch.

        :param str instance_id: The instance identifier.
        :param str id: The instance disk identifier.
        :param InstanceDiskPatch instance_disk_patch: The instance disk patch.
        :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 `InstanceDisk` object
        """

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

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

        data = json.dumps(instance_disk_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/disks/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       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'

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces'.format(
            **path_param_dict)
        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',
            *,
            allow_ip_spoofing: bool = None,
            name: str = None,
            primary_ipv4_address: str = None,
            security_groups: List['SecurityGroupIdentity'] = None,
            **kwargs) -> DetailedResponse:
        """
        Create a network interface on an instance.

        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 bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If false, source IP spoofing is
               prevented on this interface. If true, source IP spoofing is allowed on this
               interface.
        :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,
            'allow_ip_spoofing': allow_ip_spoofing,
            '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'

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces'.format(
            **path_param_dict)
        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 a 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'))

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{id}'.format(
            **path_param_dict)
        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 a 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'

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{id}'.format(
            **path_param_dict)
        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,
            network_interface_patch: 'NetworkInterfacePatch',
            **kwargs) -> DetailedResponse:
        """
        Update a network interface.

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

        :param str instance_id: The instance identifier.
        :param str id: The network interface identifier.
        :param NetworkInterfacePatch network_interface_patch: The network interface
               patch.
        :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')
        if network_interface_patch is None:
            raise ValueError('network_interface_patch must be provided')
        if isinstance(network_interface_patch, NetworkInterfacePatch):
            network_interface_patch = convert_model(network_interface_patch)
        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 = json.dumps(network_interface_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['instance_id', 'network_interface_id']
        path_param_values = self.encode_path_vars(instance_id,
                                                  network_interface_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{network_interface_id}/floating_ips'.format(
            **path_param_dict)
        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 a floating IP from a network interface.

        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'))

        path_param_keys = ['instance_id', 'network_interface_id', 'id']
        path_param_values = self.encode_path_vars(instance_id,
                                                  network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{network_interface_id}/floating_ips/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['instance_id', 'network_interface_id', 'id']
        path_param_values = self.encode_path_vars(instance_id,
                                                  network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{network_interface_id}/floating_ips/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['instance_id', 'network_interface_id', 'id']
        path_param_values = self.encode_path_vars(instance_id,
                                                  network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/network_interfaces/{network_interface_id}/floating_ips/{id}'.format(
            **path_param_dict)
        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 attachments on an instance.

        This request lists all volume attachments on 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'

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/volume_attachments'.format(
            **path_param_dict)
        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',
            *,
            delete_volume_on_instance_delete: bool = None,
            name: str = None,
            **kwargs) -> DetailedResponse:
        """
        Create a volume attachment on 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 bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :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 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,
            'delete_volume_on_instance_delete':
                delete_volume_on_instance_delete,
            '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'

        path_param_keys = ['instance_id']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/volume_attachments'.format(
            **path_param_dict)
        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.

        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'))

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/volume_attachments/{id}'.format(
            **path_param_dict)
        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 a 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'

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/volume_attachments/{id}'.format(
            **path_param_dict)
        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,
            volume_attachment_patch: 'VolumeAttachmentPatch',
            **kwargs) -> DetailedResponse:
        """
        Update a volume attachment.

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

        :param str instance_id: The instance identifier.
        :param str id: The volume attachment identifier.
        :param VolumeAttachmentPatch volume_attachment_patch: The volume attachment
               patch.
        :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')
        if volume_attachment_patch is None:
            raise ValueError('volume_attachment_patch must be provided')
        if isinstance(volume_attachment_patch, VolumeAttachmentPatch):
            volume_attachment_patch = convert_model(volume_attachment_patch)
        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 = json.dumps(volume_attachment_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['instance_id', 'id']
        path_param_values = self.encode_path_vars(instance_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/volume_attachments/{id}'.format(
            **path_param_dict)
        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.

        This request lists all instance groups 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 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'],
            *,
            application_port: int = None,
            load_balancer: 'LoadBalancerIdentity' = None,
            load_balancer_pool: 'LoadBalancerPoolIdentity' = None,
            membership_count: int = None,
            name: str = 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 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 int membership_count: (optional) The number of instances in the
               instance group.
        :param str name: (optional) The user-defined name for this instance group.
        :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,
            'application_port': application_port,
            'load_balancer': load_balancer,
            'load_balancer_pool': load_balancer_pool,
            'membership_count': membership_count,
            '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 = '/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 an 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{id}'.format(**path_param_dict)
        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 an 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{id}'.format(**path_param_dict)
        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,
                              instance_group_patch: 'InstanceGroupPatch',
                              **kwargs) -> DetailedResponse:
        """
        Update an 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 InstanceGroupPatch instance_group_patch: The instance group patch.
        :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_group_patch is None:
            raise ValueError('instance_group_patch must be provided')
        if isinstance(instance_group_patch, InstanceGroupPatch):
            instance_group_patch = convert_model(instance_group_patch)
        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 = json.dumps(instance_group_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{id}'.format(**path_param_dict)
        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 an 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'))

        path_param_keys = ['instance_group_id']
        path_param_values = self.encode_path_vars(instance_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/load_balancer'.format(
            **path_param_dict)
        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,
                                     *,
                                     start: str = None,
                                     limit: int = None,
                                     **kwargs) -> DetailedResponse:
        """
        List all managers for an instance group.

        This request lists all managers for an instance group.

        :param str instance_group_id: The instance 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 `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,
            'start': start,
            'limit': limit
        }

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

        path_param_keys = ['instance_group_id']
        path_param_values = self.encode_path_vars(instance_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers'.format(
            **path_param_dict)
        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 a manager for an instance group.

        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'

        path_param_keys = ['instance_group_id']
        path_param_values = self.encode_path_vars(instance_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers'.format(
            **path_param_dict)
        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 an 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'))

        path_param_keys = ['instance_group_id', 'id']
        path_param_values = self.encode_path_vars(instance_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{id}'.format(
            **path_param_dict)
        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 an instance group manager.

        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'

        path_param_keys = ['instance_group_id', 'id']
        path_param_values = self.encode_path_vars(instance_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{id}'.format(
            **path_param_dict)
        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,
            instance_group_manager_patch: 'InstanceGroupManagerPatch',
            **kwargs) -> DetailedResponse:
        """
        Update an 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 InstanceGroupManagerPatch instance_group_manager_patch: The instance
               group manager patch.
        :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')
        if instance_group_manager_patch is None:
            raise ValueError('instance_group_manager_patch must be provided')
        if isinstance(instance_group_manager_patch, InstanceGroupManagerPatch):
            instance_group_manager_patch = convert_model(
                instance_group_manager_patch)
        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 = json.dumps(instance_group_manager_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['instance_group_id', 'id']
        path_param_values = self.encode_path_vars(instance_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{id}'.format(
            **path_param_dict)
        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_actions(self,
                                            instance_group_id: str,
                                            instance_group_manager_id: str,
                                            *,
                                            start: str = None,
                                            limit: int = None,
                                            **kwargs) -> DetailedResponse:
        """
        List all actions for an instance group manager.

        This request lists all instance group actions 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 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 `InstanceGroupManagerActionsCollection` 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_actions')
        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'

        path_param_keys = ['instance_group_id', 'instance_group_manager_id']
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/actions'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_instance_group_manager_action(
            self, instance_group_id: str, instance_group_manager_id: str,
            instance_group_manager_action_prototype:
        'InstanceGroupManagerActionPrototype', **kwargs) -> DetailedResponse:
        """
        Create an instance group manager action.

        This request creates a new instance group manager action.

        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param InstanceGroupManagerActionPrototype
               instance_group_manager_action_prototype: The instance group manager action
               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 `InstanceGroupManagerAction` 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_action_prototype is None:
            raise ValueError(
                'instance_group_manager_action_prototype must be provided')
        if isinstance(instance_group_manager_action_prototype,
                      InstanceGroupManagerActionPrototype):
            instance_group_manager_action_prototype = convert_model(
                instance_group_manager_action_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_instance_group_manager_action')
        headers.update(sdk_headers)

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

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

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

        path_param_keys = ['instance_group_id', 'instance_group_manager_id']
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/actions'.format(
            **path_param_dict)
        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_action(self, instance_group_id: str,
                                             instance_group_manager_id: str,
                                             id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Delete specified instance group manager action.

        This request deletes an instance group manager action. 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 action 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_action')
        headers.update(sdk_headers)

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

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

        path_param_keys = [
            'instance_group_id', 'instance_group_manager_id', 'id'
        ]
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/actions/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

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

        This request retrieves a single instance group manager action 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 action 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 `InstanceGroupManagerAction` 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_action')
        headers.update(sdk_headers)

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

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

        path_param_keys = [
            'instance_group_id', 'instance_group_manager_id', 'id'
        ]
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/actions/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_instance_group_manager_action(
            self, instance_group_id: str, instance_group_manager_id: str,
            id: str, instance_group_manager_action_patch:
        'InstanceGroupManagerActionPatch', **kwargs) -> DetailedResponse:
        """
        Update specified instance group manager action.

        This request updates an instance group manager action.

        :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 action identifier.
        :param InstanceGroupManagerActionPatch instance_group_manager_action_patch:
               The instance group manager action patch.
        :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 `InstanceGroupManagerAction` 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')
        if instance_group_manager_action_patch is None:
            raise ValueError(
                'instance_group_manager_action_patch must be provided')
        if isinstance(instance_group_manager_action_patch,
                      InstanceGroupManagerActionPatch):
            instance_group_manager_action_patch = convert_model(
                instance_group_manager_action_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_instance_group_manager_action')
        headers.update(sdk_headers)

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

        data = json.dumps(instance_group_manager_action_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = [
            'instance_group_id', 'instance_group_manager_id', 'id'
        ]
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/actions/{id}'.format(
            **path_param_dict)
        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,
                                             *,
                                             start: str = None,
                                             limit: int = None,
                                             **kwargs) -> DetailedResponse:
        """
        List all policies for an instance group manager.

        This request lists 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 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 `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,
            'start': start,
            'limit': limit
        }

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

        path_param_keys = ['instance_group_id', 'instance_group_manager_id']
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/policies'.format(
            **path_param_dict)
        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 a policy for an instance group manager.

        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'

        path_param_keys = ['instance_group_id', 'instance_group_manager_id']
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/policies'.format(
            **path_param_dict)
        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 an 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'))

        path_param_keys = [
            'instance_group_id', 'instance_group_manager_id', 'id'
        ]
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/policies/{id}'.format(
            **path_param_dict)
        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 an 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'

        path_param_keys = [
            'instance_group_id', 'instance_group_manager_id', 'id'
        ]
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/policies/{id}'.format(
            **path_param_dict)
        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, instance_group_manager_policy_patch:
        'InstanceGroupManagerPolicyPatch', **kwargs) -> DetailedResponse:
        """
        Update an 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 InstanceGroupManagerPolicyPatch instance_group_manager_policy_patch:
               The instance group manager policy patch.
        :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')
        if instance_group_manager_policy_patch is None:
            raise ValueError(
                'instance_group_manager_policy_patch must be provided')
        if isinstance(instance_group_manager_policy_patch,
                      InstanceGroupManagerPolicyPatch):
            instance_group_manager_policy_patch = convert_model(
                instance_group_manager_policy_patch)
        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 = json.dumps(instance_group_manager_policy_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = [
            'instance_group_id', 'instance_group_manager_id', 'id'
        ]
        path_param_values = self.encode_path_vars(instance_group_id,
                                                  instance_group_manager_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/managers/{instance_group_manager_id}/policies/{id}'.format(
            **path_param_dict)
        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 an 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'))

        path_param_keys = ['instance_group_id']
        path_param_values = self.encode_path_vars(instance_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/memberships'.format(
            **path_param_dict)
        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,
                                        *,
                                        start: str = None,
                                        limit: int = None,
                                        **kwargs) -> DetailedResponse:
        """
        List all memberships for an instance group.

        This request lists all instance group memberships for an instance group.

        :param str instance_group_id: The instance 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 `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,
            'start': start,
            'limit': limit
        }

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

        path_param_keys = ['instance_group_id']
        path_param_values = self.encode_path_vars(instance_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/memberships'.format(
            **path_param_dict)
        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 an 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'))

        path_param_keys = ['instance_group_id', 'id']
        path_param_values = self.encode_path_vars(instance_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/memberships/{id}'.format(
            **path_param_dict)
        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 an 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'

        path_param_keys = ['instance_group_id', 'id']
        path_param_values = self.encode_path_vars(instance_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/memberships/{id}'.format(
            **path_param_dict)
        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,
            instance_group_membership_patch: 'InstanceGroupMembershipPatch',
            **kwargs) -> DetailedResponse:
        """
        Update an 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 InstanceGroupMembershipPatch instance_group_membership_patch: The
               instance group membership patch.
        :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')
        if instance_group_membership_patch is None:
            raise ValueError('instance_group_membership_patch must be provided')
        if isinstance(instance_group_membership_patch,
                      InstanceGroupMembershipPatch):
            instance_group_membership_patch = convert_model(
                instance_group_membership_patch)
        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 = json.dumps(instance_group_membership_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['instance_group_id', 'id']
        path_param_values = self.encode_path_vars(instance_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instance_groups/{instance_group_id}/memberships/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Dedicated hosts
    #########################

    def list_dedicated_host_groups(self,
                                   *,
                                   start: str = None,
                                   limit: int = None,
                                   resource_group_id: str = None,
                                   zone_name: str = None,
                                   **kwargs) -> DetailedResponse:
        """
        List all dedicated host groups.

        This request lists all dedicated host groups in the region. Host groups are a
        collection of dedicated hosts for placement of instances. Each dedicated host must
        belong to one and only one group. Host groups do not span zones.

        :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 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 `DedicatedHostGroupCollection` object
        """

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

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

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

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

        response = self.send(request)
        return response

    def create_dedicated_host_group(
            self,
            *,
            class_: str = None,
            family: str = None,
            zone: 'ZoneIdentity' = None,
            name: str = None,
            resource_group: 'ResourceGroupIdentity' = None,
            **kwargs) -> DetailedResponse:
        """
        Create a dedicated host group.

        This request creates a new dedicated host group.

        :param str class_: (optional) The dedicated host profile class for hosts in
               this group.
        :param str family: (optional) The dedicated host profile family for hosts
               in this group.
        :param ZoneIdentity zone: (optional) The zone this dedicated host group
               will reside in.
        :param str name: (optional) The unique user-defined name for this dedicated
               host group. 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 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 `DedicatedHostGroup` object
        """

        if zone is not None:
            zone = convert_model(zone)
        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_dedicated_host_group')
        headers.update(sdk_headers)

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

        data = {
            'class': class_,
            'family': family,
            'zone': zone,
            '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 = '/dedicated_host/groups'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_dedicated_host_group(self, id: str,
                                    **kwargs) -> DetailedResponse:
        """
        Delete a dedicated host group.

        This request deletes a dedicated host group.

        :param str id: The dedicated host 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_dedicated_host_group')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_host/groups/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_dedicated_host_group(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a dedicated host group.

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

        :param str id: The dedicated host 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 `DedicatedHostGroup` 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_dedicated_host_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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_host/groups/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_dedicated_host_group(
            self, id: str,
            dedicated_host_group_patch: 'DedicatedHostGroupPatch',
            **kwargs) -> DetailedResponse:
        """
        Update a dedicated host group.

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

        :param str id: The dedicated host group identifier.
        :param DedicatedHostGroupPatch dedicated_host_group_patch: The dedicated
               host group patch.
        :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 `DedicatedHostGroup` object
        """

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

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

        data = json.dumps(dedicated_host_group_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_host/groups/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

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

        This request lists all provisionable dedicated host profiles in the region. A
        dedicated host profile specifies the hardware characteristics for a dedicated
        host.

        :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 `DedicatedHostProfileCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_dedicated_host_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 = '/dedicated_host/profiles'
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_dedicated_host_profile(self, name: str,
                                   **kwargs) -> DetailedResponse:
        """
        Retrieve a dedicated host profile.

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

        :param str name: The dedicated host 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 `DedicatedHostProfile` 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_dedicated_host_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'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_host/profiles/{name}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def list_dedicated_hosts(self,
                             *,
                             dedicated_host_group_id: str = None,
                             start: str = None,
                             limit: int = None,
                             resource_group_id: str = None,
                             zone_name: str = None,
                             **kwargs) -> DetailedResponse:
        """
        List all dedicated hosts.

        This request lists all dedicated hosts in the region.

        :param str dedicated_host_group_id: (optional) Filters the collection to
               dedicated host groups with the specified 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 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 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 `DedicatedHostCollection` object
        """

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

        params = {
            'version': self.version,
            'generation': self.generation,
            'dedicated_host_group.id': dedicated_host_group_id,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'zone.name': zone_name
        }

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

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

        response = self.send(request)
        return response

    def create_dedicated_host(
            self, dedicated_host_prototype: 'DedicatedHostPrototype',
            **kwargs) -> DetailedResponse:
        """
        Create a dedicated host.

        This request creates a new dedicated host.

        :param DedicatedHostPrototype dedicated_host_prototype: The dedicated host
               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 `DedicatedHost` object
        """

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

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

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

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

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

        response = self.send(request)
        return response

    def list_dedicated_host_disks(self, dedicated_host_id: str,
                                  **kwargs) -> DetailedResponse:
        """
        List all disks on a dedicated host.

        This request lists all disks on a dedicated host.  A disk is a physical device
        that is locally attached to the compute node. By default, the listed disks are
        sorted by their
        `created_at` property values, with the newest disk first.

        :param str dedicated_host_id: The dedicated host 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 `DedicatedHostDiskCollection` object
        """

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

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

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

        path_param_keys = ['dedicated_host_id']
        path_param_values = self.encode_path_vars(dedicated_host_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_hosts/{dedicated_host_id}/disks'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_dedicated_host_disk(self, dedicated_host_id: str, id: str,
                                **kwargs) -> DetailedResponse:
        """
        Retrieve a dedicated host disk.

        This request retrieves a single dedicated host disk specified by the identifier in
        the URL.

        :param str dedicated_host_id: The dedicated host identifier.
        :param str id: The dedicated host disk 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 `DedicatedHostDisk` object
        """

        if dedicated_host_id is None:
            raise ValueError('dedicated_host_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_dedicated_host_disk')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['dedicated_host_id', 'id']
        path_param_values = self.encode_path_vars(dedicated_host_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_hosts/{dedicated_host_id}/disks/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_dedicated_host_disk(
            self, dedicated_host_id: str, id: str,
            dedicated_host_disk_patch: 'DedicatedHostDiskPatch',
            **kwargs) -> DetailedResponse:
        """
        Update a dedicated host disk.

        This request updates the dedicated host disk with the information in a provided
        patch.

        :param str dedicated_host_id: The dedicated host identifier.
        :param str id: The dedicated host disk identifier.
        :param DedicatedHostDiskPatch dedicated_host_disk_patch: The dedicated host
               disk patch.
        :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 `DedicatedHostDisk` object
        """

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

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

        data = json.dumps(dedicated_host_disk_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['dedicated_host_id', 'id']
        path_param_values = self.encode_path_vars(dedicated_host_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_hosts/{dedicated_host_id}/disks/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def delete_dedicated_host(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete a dedicated host.

        This request deletes a dedicated host.

        :param str id: The dedicated host 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_dedicated_host')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_hosts/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_dedicated_host(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve a dedicated host.

        This request retrieves a single dedicated host specified by the identifiers in the
        URL.

        :param str id: The dedicated host 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 `DedicatedHost` 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_dedicated_host')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_hosts/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_dedicated_host(self, id: str,
                              dedicated_host_patch: 'DedicatedHostPatch',
                              **kwargs) -> DetailedResponse:
        """
        Update a dedicated host.

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

        :param str id: The dedicated host identifier.
        :param DedicatedHostPatch dedicated_host_patch: The dedicated host patch.
        :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 `DedicatedHost` object
        """

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

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

        data = json.dumps(dedicated_host_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/dedicated_hosts/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/volume/profiles/{name}'.format(**path_param_dict)
        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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/volumes/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/volumes/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_volume(self, id: str, volume_patch: 'VolumePatch',
                      **kwargs) -> DetailedResponse:
        """
        Update a 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 VolumePatch volume_patch: The volume patch.
        :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')
        if volume_patch is None:
            raise ValueError('volume_patch must be provided')
        if isinstance(volume_patch, VolumePatch):
            volume_patch = convert_model(volume_patch)
        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 = json.dumps(volume_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/volumes/{id}'.format(**path_param_dict)
        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 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'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/regions/{name}'.format(**path_param_dict)
        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'

        path_param_keys = ['region_name']
        path_param_values = self.encode_path_vars(region_name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/regions/{region_name}/zones'.format(**path_param_dict)
        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, 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 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 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_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'

        path_param_keys = ['region_name', 'name']
        path_param_values = self.encode_path_vars(region_name, name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/regions/{region_name}/zones/{name}'.format(**path_param_dict)
        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 in the region. 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',
            *,
            floating_ip: 'PublicGatewayFloatingIPPrototype' = None,
            name: str = 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 this public gateway will reside in.
        :param PublicGatewayFloatingIPPrototype floating_ip: (optional)
        :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 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,
            'floating_ip': floating_ip,
            '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 = '/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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/public_gateways/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/public_gateways/{id}'.format(**path_param_dict)
        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,
                              public_gateway_patch: 'PublicGatewayPatch',
                              **kwargs) -> DetailedResponse:
        """
        Update a public gateway.

        This request updates a public gateway's name.

        :param str id: The public gateway identifier.
        :param PublicGatewayPatch public_gateway_patch: The public gateway patch.
        :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_patch is None:
            raise ValueError('public_gateway_patch must be provided')
        if isinstance(public_gateway_patch, PublicGatewayPatch):
            public_gateway_patch = convert_model(public_gateway_patch)
        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 = json.dumps(public_gateway_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/public_gateways/{id}'.format(**path_param_dict)
        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 lists 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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/floating_ips/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/floating_ips/{id}'.format(**path_param_dict)
        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, floating_ip_patch: 'FloatingIPPatch',
                           **kwargs) -> DetailedResponse:
        """
        Update a floating IP.

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

        :param str id: The floating IP identifier.
        :param FloatingIPPatch floating_ip_patch: The floating IP patch.
        :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 floating_ip_patch is None:
            raise ValueError('floating_ip_patch must be provided')
        if isinstance(floating_ip_patch, FloatingIPPatch):
            floating_ip_patch = convert_model(floating_ip_patch)
        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 = json.dumps(floating_ip_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/floating_ips/{id}'.format(**path_param_dict)
        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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{id}'.format(**path_param_dict)
        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, network_acl_patch: 'NetworkACLPatch',
                           **kwargs) -> DetailedResponse:
        """
        Update a network ACL.

        This request updates a network ACL's name.

        :param str id: The network ACL identifier.
        :param NetworkACLPatch network_acl_patch: The network ACL patch.
        :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_patch is None:
            raise ValueError('network_acl_patch must be provided')
        if isinstance(network_acl_patch, NetworkACLPatch):
            network_acl_patch = convert_model(network_acl_patch)
        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 = json.dumps(network_acl_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{id}'.format(**path_param_dict)
        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'

        path_param_keys = ['network_acl_id']
        path_param_values = self.encode_path_vars(network_acl_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{network_acl_id}/rules'.format(**path_param_dict)
        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 for a network ACL.

        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'

        path_param_keys = ['network_acl_id']
        path_param_values = self.encode_path_vars(network_acl_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{network_acl_id}/rules'.format(**path_param_dict)
        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 a network ACL 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'))

        path_param_keys = ['network_acl_id', 'id']
        path_param_values = self.encode_path_vars(network_acl_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{network_acl_id}/rules/{id}'.format(
            **path_param_dict)
        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 a network ACL 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'

        path_param_keys = ['network_acl_id', 'id']
        path_param_values = self.encode_path_vars(network_acl_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{network_acl_id}/rules/{id}'.format(
            **path_param_dict)
        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,
                                network_acl_rule_patch: 'NetworkACLRulePatch',
                                **kwargs) -> DetailedResponse:
        """
        Update a network ACL 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 NetworkACLRulePatch network_acl_rule_patch: The network ACL rule
               patch.
        :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 network_acl_rule_patch is None:
            raise ValueError('network_acl_rule_patch must be provided')
        if isinstance(network_acl_rule_patch, NetworkACLRulePatch):
            network_acl_rule_patch = convert_model(network_acl_rule_patch)
        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 = json.dumps(network_acl_rule_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['network_acl_id', 'id']
        path_param_values = self.encode_path_vars(network_acl_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/network_acls/{network_acl_id}/rules/{id}'.format(
            **path_param_dict)
        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 security groups in the region. Security groups provide a
        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 prototype 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{id}'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{id}'.format(**path_param_dict)
        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,
                              security_group_patch: 'SecurityGroupPatch',
                              **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 SecurityGroupPatch security_group_patch: The security group patch.
        :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')
        if security_group_patch is None:
            raise ValueError('security_group_patch must be provided')
        if isinstance(security_group_patch, SecurityGroupPatch):
            security_group_patch = convert_model(security_group_patch)
        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 = json.dumps(security_group_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{id}'.format(**path_param_dict)
        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 all network interfaces associated with a security group.

        This request lists all network interfaces associated with a 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'

        path_param_keys = ['security_group_id']
        path_param_values = self.encode_path_vars(security_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/network_interfaces'.format(
            **path_param_dict)
        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'))

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/network_interfaces/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/network_interfaces/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/network_interfaces/{id}'.format(
            **path_param_dict)
        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 rules in a security group.

        This request lists all rules in a 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'

        path_param_keys = ['security_group_id']
        path_param_values = self.encode_path_vars(security_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/rules'.format(
            **path_param_dict)
        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 rule for a security group.

        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'

        path_param_keys = ['security_group_id']
        path_param_values = self.encode_path_vars(security_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/rules'.format(
            **path_param_dict)
        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'))

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/rules/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/rules/{id}'.format(
            **path_param_dict)
        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,
            security_group_rule_patch: 'SecurityGroupRulePatch',
            **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 SecurityGroupRulePatch security_group_rule_patch: The security group
               rule patch.
        :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 security_group_rule_patch is None:
            raise ValueError('security_group_rule_patch must be provided')
        if isinstance(security_group_rule_patch, SecurityGroupRulePatch):
            security_group_rule_patch = convert_model(security_group_rule_patch)
        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 = json.dumps(security_group_rule_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/rules/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_security_group_targets(self,
                                    security_group_id: str,
                                    *,
                                    start: str = None,
                                    limit: int = None,
                                    **kwargs) -> DetailedResponse:
        """
        List all targets associated with a security group.

        This request lists all targets associated with a 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 `SecurityGroupTargetCollection` 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_targets')
        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'

        path_param_keys = ['security_group_id']
        path_param_values = self.encode_path_vars(security_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def delete_security_group_target_binding(self, security_group_id: str,
                                             id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Remove a target from a security group.

        This request removes a target from a security group. For this request to succeed,
        the target must be attached to at least one other security group.  The supplied
        target identifier can be:
        - A network interface identifier
        - An application load balancer identifier
        Security groups are stateful, so any changes to a target's security groups are
        applied to new connections. Existing connections are not affected.

        :param str security_group_id: The security group identifier.
        :param str id: The security group target 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_target_binding')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_security_group_target(self, security_group_id: str, id: str,
                                  **kwargs) -> DetailedResponse:
        """
        Retrieve a security group target.

        This request retrieves a single target specified by the identifier in the URL
        path. The target must be an existing target of the security group.

        :param str security_group_id: The security group identifier.
        :param str id: The security group target 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 `SecurityGroupTargetReference` 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_target')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def create_security_group_target_binding(self, security_group_id: str,
                                             id: str,
                                             **kwargs) -> DetailedResponse:
        """
        Add a target to a security group.

        This request adds a resource to an existing security group. The supplied target
        identifier can be:
        - A network interface identifier
        - An application load balancer identifier
        When a target is added to a security group, the security group rules are applied
        to the target. A request body is not required, and if supplied, is ignored.

        :param str security_group_id: The security group identifier.
        :param str id: The security group target 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 `SecurityGroupTargetReference` 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='create_security_group_target_binding')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params)

        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 lists all IKE policies 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 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,
                          *,
                          key_lifetime: int = None,
                          name: str = 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 int key_lifetime: (optional) The key lifetime in seconds.
        :param str name: (optional) The user-defined name for this IKE policy.
        :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,
            'key_lifetime': key_lifetime,
            '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 = '/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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ike_policies/{id}'.format(**path_param_dict)
        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 an 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ike_policies/{id}'.format(**path_param_dict)
        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, ike_policy_patch: 'IKEPolicyPatch',
                          **kwargs) -> DetailedResponse:
        """
        Update an IKE policy.

        This request updates the properties of an existing IKE policy.

        :param str id: The IKE policy identifier.
        :param IKEPolicyPatch ike_policy_patch: The IKE policy patch.
        :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')
        if ike_policy_patch is None:
            raise ValueError('ike_policy_patch must be provided')
        if isinstance(ike_policy_patch, IKEPolicyPatch):
            ike_policy_patch = convert_model(ike_policy_patch)
        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 = json.dumps(ike_policy_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ike_policies/{id}'.format(**path_param_dict)
        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 VPN gateway connections that use a specified IKE policy.

        This request lists all VPN gateway connections that use a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ike_policies/{id}/connections'.format(**path_param_dict)
        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 lists all IPsec policies 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 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,
                            *,
                            key_lifetime: int = None,
                            name: str = 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 int key_lifetime: (optional) The key lifetime in seconds.
        :param str name: (optional) The user-defined name for this IPsec policy.
        :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,
            'key_lifetime': key_lifetime,
            '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 = '/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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ipsec_policies/{id}'.format(**path_param_dict)
        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 an 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ipsec_policies/{id}'.format(**path_param_dict)
        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,
                            i_psec_policy_patch: 'IPsecPolicyPatch',
                            **kwargs) -> DetailedResponse:
        """
        Update an IPsec policy.

        This request updates the properties of an existing IPsec policy.

        :param str id: The IPsec policy identifier.
        :param IPsecPolicyPatch i_psec_policy_patch: The IPsec policy patch.
        :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')
        if i_psec_policy_patch is None:
            raise ValueError('i_psec_policy_patch must be provided')
        if isinstance(i_psec_policy_patch, IPsecPolicyPatch):
            i_psec_policy_patch = convert_model(i_psec_policy_patch)
        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 = json.dumps(i_psec_policy_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ipsec_policies/{id}'.format(**path_param_dict)
        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 VPN gateway connections that use a specified IPsec policy.

        This request lists all VPN gateway connections that use a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/ipsec_policies/{id}/connections'.format(**path_param_dict)
        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,
                          mode: str = None,
                          **kwargs) -> DetailedResponse:
        """
        List all VPN gateways.

        This request lists all VPN gateways 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 mode: (optional) Filters the collection to VPN gateways with the
               specified mode.
        :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,
            'mode': mode
        }

        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, vpn_gateway_prototype: 'VPNGatewayPrototype',
                           **kwargs) -> DetailedResponse:
        """
        Create a VPN gateway.

        This request creates a new VPN gateway.

        :param VPNGatewayPrototype vpn_gateway_prototype: The VPN gateway 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 `VPNGateway` object
        """

        if vpn_gateway_prototype is None:
            raise ValueError('vpn_gateway_prototype must be provided')
        if isinstance(vpn_gateway_prototype, VPNGatewayPrototype):
            vpn_gateway_prototype = convert_model(vpn_gateway_prototype)
        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 = json.dumps(vpn_gateway_prototype)
        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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{id}'.format(**path_param_dict)
        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, vpn_gateway_patch: 'VPNGatewayPatch',
                           **kwargs) -> DetailedResponse:
        """
        Update a VPN gateway.

        This request updates the properties of an existing VPN gateway.

        :param str id: The VPN gateway identifier.
        :param VPNGatewayPatch vpn_gateway_patch: The VPN gateway patch.
        :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')
        if vpn_gateway_patch is None:
            raise ValueError('vpn_gateway_patch must be provided')
        if isinstance(vpn_gateway_patch, VPNGatewayPatch):
            vpn_gateway_patch = convert_model(vpn_gateway_patch)
        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 = json.dumps(vpn_gateway_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{id}'.format(**path_param_dict)
        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 connections of a 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'

        path_param_keys = ['vpn_gateway_id']
        path_param_values = self.encode_path_vars(vpn_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections'.format(
            **path_param_dict)
        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,
            vpn_gateway_connection_prototype: 'VPNGatewayConnectionPrototype',
            **kwargs) -> DetailedResponse:
        """
        Create a connection for a VPN gateway.

        This request creates a new VPN gateway connection.

        :param str vpn_gateway_id: The VPN gateway identifier.
        :param VPNGatewayConnectionPrototype vpn_gateway_connection_prototype: The
               VPN gateway connection 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 `VPNGatewayConnection` object
        """

        if vpn_gateway_id is None:
            raise ValueError('vpn_gateway_id must be provided')
        if vpn_gateway_connection_prototype is None:
            raise ValueError(
                'vpn_gateway_connection_prototype must be provided')
        if isinstance(vpn_gateway_connection_prototype,
                      VPNGatewayConnectionPrototype):
            vpn_gateway_connection_prototype = convert_model(
                vpn_gateway_connection_prototype)
        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 = json.dumps(vpn_gateway_connection_prototype)
        headers['content-type'] = 'application/json'

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

        path_param_keys = ['vpn_gateway_id']
        path_param_values = self.encode_path_vars(vpn_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections'.format(
            **path_param_dict)
        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'))

        path_param_keys = ['vpn_gateway_id', 'id']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}'.format(
            **path_param_dict)
        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 a 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'

        path_param_keys = ['vpn_gateway_id', 'id']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}'.format(
            **path_param_dict)
        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,
            vpn_gateway_connection_patch: 'VPNGatewayConnectionPatch',
            **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 VPNGatewayConnectionPatch vpn_gateway_connection_patch: The VPN
               gateway connection patch.
        :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 vpn_gateway_connection_patch is None:
            raise ValueError('vpn_gateway_connection_patch must be provided')
        if isinstance(vpn_gateway_connection_patch, VPNGatewayConnectionPatch):
            vpn_gateway_connection_patch = convert_model(
                vpn_gateway_connection_patch)
        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 = json.dumps(vpn_gateway_connection_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['vpn_gateway_id', 'id']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}'.format(
            **path_param_dict)
        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.

        :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'

        path_param_keys = ['vpn_gateway_id', 'id']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local_cidrs'.format(
            **path_param_dict)
        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'))

        path_param_keys = [
            'vpn_gateway_id', 'id', 'cidr_prefix', 'prefix_length'
        ]
        path_param_values = self.encode_path_vars(vpn_gateway_id, id,
                                                  cidr_prefix, prefix_length)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local_cidrs/{cidr_prefix}/{prefix_length}'.format(
            **path_param_dict)
        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'))

        path_param_keys = [
            'vpn_gateway_id', 'id', 'cidr_prefix', 'prefix_length'
        ]
        path_param_values = self.encode_path_vars(vpn_gateway_id, id,
                                                  cidr_prefix, prefix_length)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local_cidrs/{cidr_prefix}/{prefix_length}'.format(
            **path_param_dict)
        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'))

        path_param_keys = [
            'vpn_gateway_id', 'id', 'cidr_prefix', 'prefix_length'
        ]
        path_param_values = self.encode_path_vars(vpn_gateway_id, id,
                                                  cidr_prefix, prefix_length)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local_cidrs/{cidr_prefix}/{prefix_length}'.format(
            **path_param_dict)
        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.

        :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'

        path_param_keys = ['vpn_gateway_id', 'id']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer_cidrs'.format(
            **path_param_dict)
        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'))

        path_param_keys = [
            'vpn_gateway_id', 'id', 'cidr_prefix', 'prefix_length'
        ]
        path_param_values = self.encode_path_vars(vpn_gateway_id, id,
                                                  cidr_prefix, prefix_length)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer_cidrs/{cidr_prefix}/{prefix_length}'.format(
            **path_param_dict)
        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'))

        path_param_keys = [
            'vpn_gateway_id', 'id', 'cidr_prefix', 'prefix_length'
        ]
        path_param_values = self.encode_path_vars(vpn_gateway_id, id,
                                                  cidr_prefix, prefix_length)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer_cidrs/{cidr_prefix}/{prefix_length}'.format(
            **path_param_dict)
        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'))

        path_param_keys = [
            'vpn_gateway_id', 'id', 'cidr_prefix', 'prefix_length'
        ]
        path_param_values = self.encode_path_vars(vpn_gateway_id, id,
                                                  cidr_prefix, prefix_length)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer_cidrs/{cidr_prefix}/{prefix_length}'.format(
            **path_param_dict)
        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 a 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'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancer/profiles/{name}'.format(**path_param_dict)
        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 lists all load balancers in the region.

        :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'],
            *,
            listeners: List[
                'LoadBalancerListenerPrototypeLoadBalancerContext'] = None,
            logging: 'LoadBalancerLogging' = None,
            name: str = None,
            pools: List['LoadBalancerPoolPrototype'] = None,
            profile: 'LoadBalancerProfileIdentity' = None,
            resource_group: 'ResourceGroupIdentity' = None,
            security_groups: List['SecurityGroupIdentity'] = None,
            **kwargs) -> DetailedResponse:
        """
        Create a load balancer.

        This request creates and provisions a new load balancer.

        :param bool is_public: Indicates whether this load balancer is public or
               private.
        :param List[SubnetIdentity] subnets: The subnets to provision this load
               balancer.
        :param List[LoadBalancerListenerPrototypeLoadBalancerContext] listeners:
               (optional) The listeners of this load balancer.
        :param LoadBalancerLogging logging: (optional) The logging configuration to
               use for this load balancer. See [VPC Datapath
               Logging](https://cloud.ibm.com/docs/vpc?topic=vpc-datapath-logging)
               on the logging format, fields and permitted values.
               To activate logging, the load balancer profile must support the specified
               logging
               type.
        :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[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 List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this load balancer.
               The load balancer profile must support 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 `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 logging is not None:
            logging = convert_model(logging)
        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)
        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_load_balancer')
        headers.update(sdk_headers)

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

        data = {
            'is_public': is_public,
            'subnets': subnets,
            'listeners': listeners,
            'logging': logging,
            'name': name,
            'pools': pools,
            'profile': profile,
            'resource_group': resource_group,
            '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 = '/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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{id}'.format(**path_param_dict)
        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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{id}'.format(**path_param_dict)
        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,
                             load_balancer_patch: 'LoadBalancerPatch',
                             **kwargs) -> DetailedResponse:
        """
        Update a load balancer.

        This request updates a load balancer.

        :param str id: The load balancer identifier.
        :param LoadBalancerPatch load_balancer_patch: The load balancer patch.
        :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')
        if load_balancer_patch is None:
            raise ValueError('load_balancer_patch must be provided')
        if isinstance(load_balancer_patch, LoadBalancerPatch):
            load_balancer_patch = convert_model(load_balancer_patch)
        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 = json.dumps(load_balancer_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{id}'.format(**path_param_dict)
        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 all statistics of a load balancer.

        This request lists statistics of a load balancer.

        :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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{id}/statistics'.format(**path_param_dict)
        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 for a load balancer.

        This request lists all listeners for a 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'

        path_param_keys = ['load_balancer_id']
        path_param_values = self.encode_path_vars(load_balancer_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners'.format(
            **path_param_dict)
        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,
            *,
            accept_proxy_protocol: bool = None,
            certificate_instance: 'CertificateInstanceIdentity' = None,
            connection_limit: int = None,
            default_pool: 'LoadBalancerPoolIdentity' = None,
            policies: List['LoadBalancerListenerPolicyPrototype'] = None,
            **kwargs) -> DetailedResponse:
        """
        Create a listener for a load balancer.

        This request creates a new listener for a load balancer.

        :param str load_balancer_id: The load balancer identifier.
        :param int port: The listener port number, or the inclusive lower bound of
               the port range. Each listener in the load balancer must have a unique
               `port` and `protocol` combination.
        :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`. Each listener in the load balancer must have a
               unique `port` and `protocol` combination.
        :param bool accept_proxy_protocol: (optional) If set to `true`, this
               listener will accept and forward PROXY protocol information. Supported by
               load balancers in the `application` family (otherwise always `false`).
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance used for SSL termination. It is applicable only to
               `https`
               protocol.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               associated with the listener. The specified pool must:
               - Belong to this load balancer
               - Have the same `protocol` as this listener
               - Not already be the default pool for another listener.
        :param List[LoadBalancerListenerPolicyPrototype] policies: (optional) An
               array of policies for 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,
            'accept_proxy_protocol': accept_proxy_protocol,
            'certificate_instance': certificate_instance,
            'connection_limit': connection_limit,
            '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'

        path_param_keys = ['load_balancer_id']
        path_param_values = self.encode_path_vars(load_balancer_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners'.format(
            **path_param_dict)
        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 load balancer 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'))

        path_param_keys = ['load_balancer_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{id}'.format(
            **path_param_dict)
        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 load balancer 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'

        path_param_keys = ['load_balancer_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{id}'.format(
            **path_param_dict)
        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,
            load_balancer_listener_patch: 'LoadBalancerListenerPatch',
            **kwargs) -> DetailedResponse:
        """
        Update a load balancer 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 LoadBalancerListenerPatch load_balancer_listener_patch: The load
               balancer listener patch.
        :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 load_balancer_listener_patch is None:
            raise ValueError('load_balancer_listener_patch must be provided')
        if isinstance(load_balancer_listener_patch, LoadBalancerListenerPatch):
            load_balancer_listener_patch = convert_model(
                load_balancer_listener_patch)
        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 = json.dumps(load_balancer_listener_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['load_balancer_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{id}'.format(
            **path_param_dict)
        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 for a load balancer listener.

        This request lists all policies for a 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'

        path_param_keys = ['load_balancer_id', 'listener_id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies'.format(
            **path_param_dict)
        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,
            action: str,
            priority: int,
            *,
            name: str = None,
            rules: List['LoadBalancerListenerPolicyRulePrototype'] = None,
            target: 'LoadBalancerListenerPolicyTargetPrototype' = None,
            **kwargs) -> DetailedResponse:
        """
        Create a policy for a load balancer listener.

        Creates a new policy for a load balancer listener.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str action: The policy action.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :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) An
               array of rules for this policy.
        :param LoadBalancerListenerPolicyTargetPrototype 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 action is None:
            raise ValueError('action must be provided')
        if priority is None:
            raise ValueError('priority 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 = {
            'action': action,
            'priority': priority,
            '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'

        path_param_keys = ['load_balancer_id', 'listener_id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies'.format(
            **path_param_dict)
        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 load balancer listener policy.

        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'))

        path_param_keys = ['load_balancer_id', 'listener_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{id}'.format(
            **path_param_dict)
        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 load balancer listener policy.

        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'

        path_param_keys = ['load_balancer_id', 'listener_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{id}'.format(
            **path_param_dict)
        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,
            load_balancer_listener_policy_patch:
        'LoadBalancerListenerPolicyPatch', **kwargs) -> DetailedResponse:
        """
        Update a load balancer listener policy.

        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 LoadBalancerListenerPolicyPatch load_balancer_listener_policy_patch:
               The listener policy patch.
        :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 load_balancer_listener_policy_patch is None:
            raise ValueError(
                'load_balancer_listener_policy_patch must be provided')
        if isinstance(load_balancer_listener_policy_patch,
                      LoadBalancerListenerPolicyPatch):
            load_balancer_listener_policy_patch = convert_model(
                load_balancer_listener_policy_patch)
        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 = json.dumps(load_balancer_listener_policy_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['load_balancer_id', 'listener_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{id}'.format(
            **path_param_dict)
        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 a load balancer listener policy.

        This request lists all rules of a 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'

        path_param_keys = ['load_balancer_id', 'listener_id', 'policy_id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  policy_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{policy_id}/rules'.format(
            **path_param_dict)
        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 a 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.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this field is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        :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'

        path_param_keys = ['load_balancer_id', 'listener_id', 'policy_id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  policy_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{policy_id}/rules'.format(
            **path_param_dict)
        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 load balancer listener policy rule.

        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'))

        path_param_keys = ['load_balancer_id', 'listener_id', 'policy_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  policy_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{policy_id}/rules/{id}'.format(
            **path_param_dict)
        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 load balancer listener policy rule.

        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'

        path_param_keys = ['load_balancer_id', 'listener_id', 'policy_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  policy_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{policy_id}/rules/{id}'.format(
            **path_param_dict)
        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, load_balancer_listener_policy_rule_patch:
        'LoadBalancerListenerPolicyRulePatch', **kwargs) -> DetailedResponse:
        """
        Update a load balancer listener policy rule.

        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 LoadBalancerListenerPolicyRulePatch
               load_balancer_listener_policy_rule_patch: The listener policy rule patch.
        :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')
        if load_balancer_listener_policy_rule_patch is None:
            raise ValueError(
                'load_balancer_listener_policy_rule_patch must be provided')
        if isinstance(load_balancer_listener_policy_rule_patch,
                      LoadBalancerListenerPolicyRulePatch):
            load_balancer_listener_policy_rule_patch = convert_model(
                load_balancer_listener_policy_rule_patch)
        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 = json.dumps(load_balancer_listener_policy_rule_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['load_balancer_id', 'listener_id', 'policy_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, listener_id,
                                                  policy_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/listeners/{listener_id}/policies/{policy_id}/rules/{id}'.format(
            **path_param_dict)
        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 a load balancer.

        This request lists all pools of a 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'

        path_param_keys = ['load_balancer_id']
        path_param_values = self.encode_path_vars(load_balancer_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools'.format(
            **path_param_dict)
        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,
            health_monitor: 'LoadBalancerPoolHealthMonitorPrototype',
            protocol: str,
            *,
            members: List['LoadBalancerPoolMemberPrototype'] = None,
            name: str = None,
            proxy_protocol: str = 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 LoadBalancerPoolHealthMonitorPrototype health_monitor: The health
               monitor of this pool.
        :param str protocol: The protocol used for this load balancer pool. Load
               balancers in the `network` family support `tcp`. Load balancers in the
               `application` family support `tcp`, `http`, and
               `https`.
        :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 pool
               member of any other load balancer in the same VPC.
        :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 str proxy_protocol: (optional) The PROXY protocol setting for this
               pool:
               - `v1`: Enabled with version 1 (human-readable header format)
               - `v2`: Enabled with version 2 (binary header format)
               - `disabled`: Disabled
               Supported by load balancers in the `application` family (otherwise always
               `disabled`).
        :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 health_monitor is None:
            raise ValueError('health_monitor must be provided')
        if protocol is None:
            raise ValueError('protocol 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,
            'health_monitor': health_monitor,
            'protocol': protocol,
            'members': members,
            'name': name,
            'proxy_protocol': proxy_protocol,
            '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'

        path_param_keys = ['load_balancer_id']
        path_param_values = self.encode_path_vars(load_balancer_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools'.format(
            **path_param_dict)
        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 load balancer pool.

        This request deletes a load balancer pool. This operation cannot be reversed. The
        pool must not currently be the default pool for any listener in the load balancer.

        :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'))

        path_param_keys = ['load_balancer_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{id}'.format(
            **path_param_dict)
        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'

        path_param_keys = ['load_balancer_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{id}'.format(
            **path_param_dict)
        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,
            load_balancer_pool_patch: 'LoadBalancerPoolPatch',
            **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 LoadBalancerPoolPatch load_balancer_pool_patch: The load balancer
               pool patch.
        :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 load_balancer_pool_patch is None:
            raise ValueError('load_balancer_pool_patch must be provided')
        if isinstance(load_balancer_pool_patch, LoadBalancerPoolPatch):
            load_balancer_pool_patch = convert_model(load_balancer_pool_patch)
        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 = json.dumps(load_balancer_pool_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['load_balancer_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{id}'.format(
            **path_param_dict)
        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 a load balancer pool.

        This request lists all members of a load balancer 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'

        path_param_keys = ['load_balancer_id', 'pool_id']
        path_param_values = self.encode_path_vars(load_balancer_id, pool_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{pool_id}/members'.format(
            **path_param_dict)
        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 a 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 virtual server
               instances. Load balancers in the `application` family support IP addresses.
        :param int weight: (optional) Weight of the server member. Applicable only
               if the pool algorithm 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'

        path_param_keys = ['load_balancer_id', 'pool_id']
        path_param_values = self.encode_path_vars(load_balancer_id, pool_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{pool_id}/members'.format(
            **path_param_dict)
        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:
        """
        Replace load balancer pool members.

        This request replaces the existing members of the load balancer pool with new
        members created from the 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'

        path_param_keys = ['load_balancer_id', 'pool_id']
        path_param_values = self.encode_path_vars(load_balancer_id, pool_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{pool_id}/members'.format(
            **path_param_dict)
        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 load balancer pool member.

        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'))

        path_param_keys = ['load_balancer_id', 'pool_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, pool_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{pool_id}/members/{id}'.format(
            **path_param_dict)
        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 load balancer pool member.

        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'

        path_param_keys = ['load_balancer_id', 'pool_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, pool_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{pool_id}/members/{id}'.format(
            **path_param_dict)
        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,
            load_balancer_pool_member_patch: 'LoadBalancerPoolMemberPatch',
            **kwargs) -> DetailedResponse:
        """
        Update a load balancer pool member.

        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 LoadBalancerPoolMemberPatch load_balancer_pool_member_patch: The
               load balancer pool member patch.
        :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 load_balancer_pool_member_patch is None:
            raise ValueError('load_balancer_pool_member_patch must be provided')
        if isinstance(load_balancer_pool_member_patch,
                      LoadBalancerPoolMemberPatch):
            load_balancer_pool_member_patch = convert_model(
                load_balancer_pool_member_patch)
        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 = json.dumps(load_balancer_pool_member_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['load_balancer_id', 'pool_id', 'id']
        path_param_values = self.encode_path_vars(load_balancer_id, pool_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancers/{load_balancer_id}/pools/{pool_id}/members/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Endpoint gateways
    #########################

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

        This request lists all endpoint gateways in the region. An endpoint gateway maps
        one or more reserved IPs in a VPC to a target outside the VPC.

        :param str name: (optional) Filters the collection to resources with the
               exact specified name.
        :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 `EndpointGatewayCollection` object
        """

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

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

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

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

        response = self.send(request)
        return response

    def create_endpoint_gateway(self,
                                target: 'EndpointGatewayTargetPrototype',
                                vpc: 'VPCIdentity',
                                *,
                                ips: List['EndpointGatewayReservedIP'] = None,
                                name: str = None,
                                resource_group: 'ResourceGroupIdentity' = None,
                                **kwargs) -> DetailedResponse:
        """
        Create an endpoint gateway.

        This request creates a new endpoint gateway. An endpoint gateway maps one or more
        reserved IPs in a VPC to a target outside the VPC.

        :param EndpointGatewayTargetPrototype target: The target for this endpoint
               gateway.
        :param VPCIdentity vpc: The VPC this endpoint gateway will serve.
        :param List[EndpointGatewayReservedIP] ips: (optional) An array of reserved
               IPs to bind to this endpoint gateway. At most one reserved IP per zone is
               allowed.
        :param str name: (optional) The user-defined name for this endpoint
               gateway. If unspecified, the name will be a hyphenated list of
               randomly-selected words. Names must be unique within the VPC this endpoint
               gateway is serving.
        :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 `EndpointGateway` object
        """

        if target is None:
            raise ValueError('target must be provided')
        if vpc is None:
            raise ValueError('vpc must be provided')
        target = convert_model(target)
        vpc = convert_model(vpc)
        if ips is not None:
            ips = [convert_model(x) for x in ips]
        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_endpoint_gateway')
        headers.update(sdk_headers)

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

        data = {
            'target': target,
            'vpc': vpc,
            'ips': ips,
            '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 = '/endpoint_gateways'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response

    def list_endpoint_gateway_ips(self,
                                  endpoint_gateway_id: str,
                                  *,
                                  start: str = None,
                                  limit: int = None,
                                  sort: str = None,
                                  **kwargs) -> DetailedResponse:
        """
        List all reserved IPs bound to an endpoint gateway.

        This request lists all reserved IPs bound to an endpoint gateway.

        :param str endpoint_gateway_id: The endpoint gateway 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 sort: (optional) Sorts the returned collection by the specified
               field name in ascending order. A `-` may be prepended to the field name to
               sort in descending order. For example, the value
               `-created_at` sorts the collection by the `created_at` field in descending
               order, and the value `name` sorts it by the `name` field in ascending
               order.
        :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 `ReservedIPCollectionEndpointGatewayContext` object
        """

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

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

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

        path_param_keys = ['endpoint_gateway_id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def remove_endpoint_gateway_ip(self, endpoint_gateway_id: str, id: str,
                                   **kwargs) -> DetailedResponse:
        """
        Unbind a reserved IP from an endpoint gateway.

        This request unbinds the specified reserved IP from the specified endpoint
        gateway. If the reserved IP has `auto_delete` set to `true`, the reserved IP will
        be deleted.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str id: The reserved 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 endpoint_gateway_id is None:
            raise ValueError('endpoint_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='remove_endpoint_gateway_ip')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['endpoint_gateway_id', 'id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_endpoint_gateway_ip(self, endpoint_gateway_id: str, id: str,
                                **kwargs) -> DetailedResponse:
        """
        Retrieve a reserved IP bound to an endpoint gateway.

        This request a retrieves the specified reserved IP address if it is bound to the
        endpoint gateway specified in the URL.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str id: The reserved 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 `ReservedIP` object
        """

        if endpoint_gateway_id is None:
            raise ValueError('endpoint_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_endpoint_gateway_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'

        path_param_keys = ['endpoint_gateway_id', 'id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def add_endpoint_gateway_ip(self, endpoint_gateway_id: str, id: str,
                                **kwargs) -> DetailedResponse:
        """
        Bind a reserved IP to an endpoint gateway.

        This request binds the specified reserved IP to the specified endpoint gateway.
        The reserved IP:
        - must currently be unbound
        - must not be in the same zone as any other reserved IP bound to the endpoint
        gateway.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str id: The reserved 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 `ReservedIP` object
        """

        if endpoint_gateway_id is None:
            raise ValueError('endpoint_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='add_endpoint_gateway_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'

        path_param_keys = ['endpoint_gateway_id', 'id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips/{id}'.format(
            **path_param_dict)
        request = self.prepare_request(method='PUT',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def delete_endpoint_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete an endpoint gateway.

        This request deletes an endpoint gateway. This operation cannot be reversed.
        Reserved IPs that were bound to the endpoint gateway will be released if their
        `auto_delete` property is set to true.

        :param str id: The endpoint 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_endpoint_gateway')
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def get_endpoint_gateway(self, id: str, **kwargs) -> DetailedResponse:
        """
        Retrieve an endpoint gateway.

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

        :param str id: The endpoint 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 `EndpointGateway` 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_endpoint_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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET',
                                       url=url,
                                       headers=headers,
                                       params=params)

        response = self.send(request)
        return response

    def update_endpoint_gateway(self, id: str,
                                endpoint_gateway_patch: 'EndpointGatewayPatch',
                                **kwargs) -> DetailedResponse:
        """
        Update an endpoint gateway.

        This request updates an endpoint gateway's name.

        :param str id: The endpoint gateway identifier.
        :param EndpointGatewayPatch endpoint_gateway_patch: The endpoint gateway
               patch.
        :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 `EndpointGateway` object
        """

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

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

        data = json.dumps(endpoint_gateway_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{id}'.format(**path_param_dict)
        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 lists 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: 'FlowLogCollectorTargetPrototype',
            *,
            active: bool = None,
            name: str = 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 FlowLogCollectorTargetPrototype target: The target this collector
               will 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 bool active: (optional) Indicates whether this collector will be
               active upon creation.
        :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 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,
            'active': active,
            '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 = '/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 a 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'))

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/flow_log_collectors/{id}'.format(**path_param_dict)
        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 a 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'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/flow_log_collectors/{id}'.format(**path_param_dict)
        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, flow_log_collector_patch: 'FlowLogCollectorPatch',
            **kwargs) -> DetailedResponse:
        """
        Update a 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 FlowLogCollectorPatch flow_log_collector_patch: The flow log
               collector patch.
        :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')
        if flow_log_collector_patch is None:
            raise ValueError('flow_log_collector_patch must be provided')
        if isinstance(flow_log_collector_patch, FlowLogCollectorPatch):
            flow_log_collector_patch = convert_model(flow_log_collector_patch)
        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 = json.dumps(flow_log_collector_patch)
        headers['content-type'] = 'application/merge-patch+json'

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/flow_log_collectors/{id}'.format(**path_param_dict)
        request = self.prepare_request(method='PATCH',
                                       url=url,
                                       headers=headers,
                                       params=params,
                                       data=data)

        response = self.send(request)
        return response


class ListSubnetReservedIpsEnums:
    """
    Enums for list_subnet_reserved_ips parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified field name in ascending order. A
        `-` may be prepended to the field name to sort in descending order. For example,
        the value
        `-created_at` sorts the collection by the `created_at` field in descending order,
        and the value `name` sorts it by the `name` field in ascending order.
        """
        CREATED_AT = 'created_at'
        NAME = 'name'
        ADDRESS = 'address'


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 ListVpnGatewaysEnums:
    """
    Enums for list_vpn_gateways parameters.
    """

    class Mode(str, Enum):
        """
        Filters the collection to VPN gateways with the specified mode.
        """
        POLICY = 'policy'
        ROUTE = 'route'


class ListEndpointGatewayIpsEnums:
    """
    Enums for list_endpoint_gateway_ips parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified field name in ascending order. A
        `-` may be prepended to the field name to sort in descending order. For example,
        the value
        `-created_at` sorts the collection by the `created_at` field in descending order,
        and the value `name` sorts it by the `name` field in ascending order.
        """
        CREATED_AT = 'created_at'
        NAME = 'name'
        ADDRESS = 'address'


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 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 str href: The URL for this address prefix.
    :attr str id: The unique identifier for this address prefix.
    :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 name: The user-defined name for this address prefix. Names must be
          unique within the VPC the address prefix resides in.
    :attr ZoneReference zone: The zone this address prefix resides in.
    """

    def __init__(self, cidr: str, created_at: datetime, has_subnets: bool,
                 href: str, id: str, is_default: bool, name: str,
                 zone: 'ZoneReference') -> None:
        """
        Initialize a AddressPrefix object.

        :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 str href: The URL for this address prefix.
        :param str id: The unique identifier for this address prefix.
        :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 name: The user-defined name for this address prefix. Names must
               be unique within the VPC the address prefix resides in.
        :param ZoneReference zone: The zone this address prefix resides in.
        """
        self.cidr = cidr
        self.created_at = created_at
        self.has_subnets = has_subnets
        self.href = href
        self.id = id
        self.is_default = is_default
        self.name = name
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefix':
        """Initialize a AddressPrefix object from a json dictionary."""
        args = {}
        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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in AddressPrefix JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 List[AddressPrefix] address_prefixes: Collection of address prefixes.
    :attr AddressPrefixCollectionFirst first: A link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 address_prefixes: List['AddressPrefix'],
                 first: 'AddressPrefixCollectionFirst',
                 limit: int,
                 total_count: int,
                 *,
                 next: 'AddressPrefixCollectionNext' = None) -> None:
        """
        Initialize a AddressPrefixCollection object.

        :param List[AddressPrefix] address_prefixes: Collection of address
               prefixes.
        :param AddressPrefixCollectionFirst first: A link 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 AddressPrefixCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.address_prefixes = address_prefixes
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollection':
        """Initialize a AddressPrefixCollection object from a json dictionary."""
        args = {}
        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'
            )
        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'
            )
        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,
                   'address_prefixes') and self.address_prefixes is not None:
            _dict['address_prefixes'] = [
                x.to_dict() for x in self.address_prefixes
            ]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a AddressPrefixCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a AddressPrefixCollectionNext object.

        :param str href: The URL for a 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 AddressPrefixPatch():
    """
    AddressPrefixPatch.

    :attr 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.
    :attr str name: (optional) The user-defined name for this address prefix. Names
          must be unique within the VPC the address prefix resides in.
    """

    def __init__(self, *, is_default: bool = None, name: str = None) -> None:
        """
        Initialize a AddressPrefixPatch object.

        :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 str name: (optional) The user-defined name for this address prefix.
               Names must be unique within the VPC the address prefix resides in.
        """
        self.is_default = is_default
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixPatch':
        """Initialize a AddressPrefixPatch object from a json dictionary."""
        args = {}
        if 'is_default' in _dict:
            args['is_default'] = _dict.get('is_default')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        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 AddressPrefixPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixPatch') -> 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 DedicatedHost():
    """
    DedicatedHost.

    :attr int available_memory: The amount of memory in gibibytes that is currently
          available for instances.
    :attr VCPU available_vcpu: The available VCPU for the dedicated host.
    :attr datetime created_at: The date and time that the dedicated host was
          created.
    :attr str crn: The CRN for this dedicated host.
    :attr List[DedicatedHostDisk] disks: Collection of the dedicated host's disks.
    :attr DedicatedHostGroupReference group: The dedicated host group this dedicated
          host is in.
    :attr str href: The URL for this dedicated host.
    :attr str id: The unique identifier for this dedicated host.
    :attr bool instance_placement_enabled: If set to true, instances can be placed
          on this dedicated host.
    :attr List[InstanceReference] instances: Array of instances that are allocated
          to this dedicated host.
    :attr str lifecycle_state: The lifecycle state of the dedicated host resource.
    :attr int memory: The total amount of memory in gibibytes for this host.
    :attr str name: The unique user-defined name for this dedicated host. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileReference profile: The profile this dedicated host
          uses.
    :attr bool provisionable: Indicates whether this dedicated host is available for
          instance creation.
    :attr ResourceGroupReference resource_group: The resource group for this
          dedicated host.
    :attr str resource_type: The type of resource referenced.
    :attr int socket_count: The total number of sockets for this host.
    :attr str state: The administrative state of the dedicated host.
          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 dedicated host on which the
          unexpected property value was encountered.
    :attr List[InstanceProfileReference] supported_instance_profiles: Array of
          instance profiles that can be used by instances placed on this dedicated host.
    :attr VCPU vcpu: The total VCPU of the dedicated host.
    :attr ZoneReference zone: The zone this dedicated host resides in.
    """

    def __init__(self, available_memory: int, available_vcpu: 'VCPU',
                 created_at: datetime, crn: str,
                 disks: List['DedicatedHostDisk'],
                 group: 'DedicatedHostGroupReference', href: str, id: str,
                 instance_placement_enabled: bool,
                 instances: List['InstanceReference'], lifecycle_state: str,
                 memory: int, name: str,
                 profile: 'DedicatedHostProfileReference', provisionable: bool,
                 resource_group: 'ResourceGroupReference', resource_type: str,
                 socket_count: int, state: str,
                 supported_instance_profiles: List['InstanceProfileReference'],
                 vcpu: 'VCPU', zone: 'ZoneReference') -> None:
        """
        Initialize a DedicatedHost object.

        :param int available_memory: The amount of memory in gibibytes that is
               currently available for instances.
        :param VCPU available_vcpu: The available VCPU for the dedicated host.
        :param datetime created_at: The date and time that the dedicated host was
               created.
        :param str crn: The CRN for this dedicated host.
        :param List[DedicatedHostDisk] disks: Collection of the dedicated host's
               disks.
        :param DedicatedHostGroupReference group: The dedicated host group this
               dedicated host is in.
        :param str href: The URL for this dedicated host.
        :param str id: The unique identifier for this dedicated host.
        :param bool instance_placement_enabled: If set to true, instances can be
               placed on this dedicated host.
        :param List[InstanceReference] instances: Array of instances that are
               allocated to this dedicated host.
        :param str lifecycle_state: The lifecycle state of the dedicated host
               resource.
        :param int memory: The total amount of memory in gibibytes for this host.
        :param str name: The unique user-defined name for this dedicated host. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param DedicatedHostProfileReference profile: The profile this dedicated
               host uses.
        :param bool provisionable: Indicates whether this dedicated host is
               available for instance creation.
        :param ResourceGroupReference resource_group: The resource group for this
               dedicated host.
        :param str resource_type: The type of resource referenced.
        :param int socket_count: The total number of sockets for this host.
        :param str state: The administrative state of the dedicated host.
               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 dedicated
               host on which the unexpected property value was encountered.
        :param List[InstanceProfileReference] supported_instance_profiles: Array of
               instance profiles that can be used by instances placed on this dedicated
               host.
        :param VCPU vcpu: The total VCPU of the dedicated host.
        :param ZoneReference zone: The zone this dedicated host resides in.
        """
        self.available_memory = available_memory
        self.available_vcpu = available_vcpu
        self.created_at = created_at
        self.crn = crn
        self.disks = disks
        self.group = group
        self.href = href
        self.id = id
        self.instance_placement_enabled = instance_placement_enabled
        self.instances = instances
        self.lifecycle_state = lifecycle_state
        self.memory = memory
        self.name = name
        self.profile = profile
        self.provisionable = provisionable
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.socket_count = socket_count
        self.state = state
        self.supported_instance_profiles = supported_instance_profiles
        self.vcpu = vcpu
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHost':
        """Initialize a DedicatedHost object from a json dictionary."""
        args = {}
        if 'available_memory' in _dict:
            args['available_memory'] = _dict.get('available_memory')
        else:
            raise ValueError(
                'Required property \'available_memory\' not present in DedicatedHost JSON'
            )
        if 'available_vcpu' in _dict:
            args['available_vcpu'] = VCPU.from_dict(_dict.get('available_vcpu'))
        else:
            raise ValueError(
                'Required property \'available_vcpu\' not present in DedicatedHost 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 DedicatedHost JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DedicatedHost JSON')
        if 'disks' in _dict:
            args['disks'] = [
                DedicatedHostDisk.from_dict(x) for x in _dict.get('disks')
            ]
        else:
            raise ValueError(
                'Required property \'disks\' not present in DedicatedHost JSON')
        if 'group' in _dict:
            args['group'] = DedicatedHostGroupReference.from_dict(
                _dict.get('group'))
        else:
            raise ValueError(
                'Required property \'group\' not present in DedicatedHost JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHost JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DedicatedHost JSON')
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get(
                'instance_placement_enabled')
        else:
            raise ValueError(
                'Required property \'instance_placement_enabled\' not present in DedicatedHost JSON'
            )
        if 'instances' in _dict:
            args['instances'] = [
                InstanceReference.from_dict(x) for x in _dict.get('instances')
            ]
        else:
            raise ValueError(
                'Required property \'instances\' not present in DedicatedHost JSON'
            )
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' not present in DedicatedHost JSON'
            )
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError(
                'Required property \'memory\' not present in DedicatedHost JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHost JSON')
        if 'profile' in _dict:
            args['profile'] = DedicatedHostProfileReference.from_dict(
                _dict.get('profile'))
        else:
            raise ValueError(
                'Required property \'profile\' not present in DedicatedHost JSON'
            )
        if 'provisionable' in _dict:
            args['provisionable'] = _dict.get('provisionable')
        else:
            raise ValueError(
                'Required property \'provisionable\' not present in DedicatedHost 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 DedicatedHost JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in DedicatedHost JSON'
            )
        if 'socket_count' in _dict:
            args['socket_count'] = _dict.get('socket_count')
        else:
            raise ValueError(
                'Required property \'socket_count\' not present in DedicatedHost JSON'
            )
        if 'state' in _dict:
            args['state'] = _dict.get('state')
        else:
            raise ValueError(
                'Required property \'state\' not present in DedicatedHost JSON')
        if 'supported_instance_profiles' in _dict:
            args['supported_instance_profiles'] = [
                InstanceProfileReference.from_dict(x)
                for x in _dict.get('supported_instance_profiles')
            ]
        else:
            raise ValueError(
                'Required property \'supported_instance_profiles\' not present in DedicatedHost JSON'
            )
        if 'vcpu' in _dict:
            args['vcpu'] = VCPU.from_dict(_dict.get('vcpu'))
        else:
            raise ValueError(
                'Required property \'vcpu\' not present in DedicatedHost JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in DedicatedHost JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHost object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'available_memory') and self.available_memory is not None:
            _dict['available_memory'] = self.available_memory
        if hasattr(self, 'available_vcpu') and self.available_vcpu is not None:
            _dict['available_vcpu'] = self.available_vcpu.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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'disks') and self.disks is not None:
            _dict['disks'] = [x.to_dict() for x in self.disks]
        if hasattr(self, 'group') and self.group is not None:
            _dict['group'] = self.group.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance_placement_enabled'
                  ) and self.instance_placement_enabled is not None:
            _dict[
                'instance_placement_enabled'] = self.instance_placement_enabled
        if hasattr(self, 'instances') and self.instances is not None:
            _dict['instances'] = [x.to_dict() for x in self.instances]
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'provisionable') and self.provisionable is not None:
            _dict['provisionable'] = self.provisionable
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'socket_count') and self.socket_count is not None:
            _dict['socket_count'] = self.socket_count
        if hasattr(self, 'state') and self.state is not None:
            _dict['state'] = self.state
        if hasattr(self, 'supported_instance_profiles'
                  ) and self.supported_instance_profiles is not None:
            _dict['supported_instance_profiles'] = [
                x.to_dict() for x in self.supported_instance_profiles
            ]
        if hasattr(self, 'vcpu') and self.vcpu is not None:
            _dict['vcpu'] = self.vcpu.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 DedicatedHost object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHost') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHost') -> 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 dedicated host resource.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        DEDICATED_HOST = 'dedicated_host'

    class StateEnum(str, Enum):
        """
        The administrative state of the dedicated host.
        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 dedicated host on which the
        unexpected property value was encountered.
        """
        AVAILABLE = 'available'
        DEGRADED = 'degraded'
        MIGRATING = 'migrating'
        UNAVAILABLE = 'unavailable'


class DedicatedHostCollection():
    """
    DedicatedHostCollection.

    :attr List[DedicatedHost] dedicated_hosts: Collection of dedicated hosts.
    :attr DedicatedHostCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr DedicatedHostCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 dedicated_hosts: List['DedicatedHost'],
                 first: 'DedicatedHostCollectionFirst',
                 limit: int,
                 total_count: int,
                 *,
                 next: 'DedicatedHostCollectionNext' = None) -> None:
        """
        Initialize a DedicatedHostCollection object.

        :param List[DedicatedHost] dedicated_hosts: Collection of dedicated hosts.
        :param DedicatedHostCollectionFirst first: A link 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 DedicatedHostCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.dedicated_hosts = dedicated_hosts
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostCollection':
        """Initialize a DedicatedHostCollection object from a json dictionary."""
        args = {}
        if 'dedicated_hosts' in _dict:
            args['dedicated_hosts'] = [
                DedicatedHost.from_dict(x) for x in _dict.get('dedicated_hosts')
            ]
        else:
            raise ValueError(
                'Required property \'dedicated_hosts\' not present in DedicatedHostCollection JSON'
            )
        if 'first' in _dict:
            args['first'] = DedicatedHostCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in DedicatedHostCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in DedicatedHostCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = DedicatedHostCollectionNext.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 DedicatedHostCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'dedicated_hosts') and self.dedicated_hosts is not None:
            _dict['dedicated_hosts'] = [
                x.to_dict() for x in self.dedicated_hosts
            ]
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostCollectionFirst':
        """Initialize a DedicatedHostCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostCollectionFirst object from 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 DedicatedHostCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostCollectionNext':
        """Initialize a DedicatedHostCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostCollectionNext object from 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 DedicatedHostCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostDisk():
    """
    DedicatedHostDisk.

    :attr int available: The remaining space left for instance placement in GB
          (gigabytes).
    :attr datetime created_at: The date and time that the disk was created.
    :attr str href: The URL for this disk.
    :attr str id: The unique identifier for this disk.
    :attr List[InstanceDiskReference] instance_disks: Instance disks that are on
          this dedicated host disk.
    :attr str interface_type: The disk interface used for attaching the disk
          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 resource on which the unexpected
          property value was encountered.
    :attr str lifecycle_state: (optional) The lifecycle state of this dedicated host
          disk.
    :attr str name: The user-defined or system-provided name for this disk.
    :attr bool provisionable: Indicates whether this dedicated host disk is
          available for instance disk creation.
    :attr str resource_type: The type of resource referenced.
    :attr int size: The size of the disk in GB (gigabytes).
    :attr List[str] supported_instance_interface_types: The instance disk interfaces
          supported for this dedicated host disk.
    """

    def __init__(self,
                 available: int,
                 created_at: datetime,
                 href: str,
                 id: str,
                 instance_disks: List['InstanceDiskReference'],
                 interface_type: str,
                 name: str,
                 provisionable: bool,
                 resource_type: str,
                 size: int,
                 supported_instance_interface_types: List[str],
                 *,
                 lifecycle_state: str = None) -> None:
        """
        Initialize a DedicatedHostDisk object.

        :param int available: The remaining space left for instance placement in GB
               (gigabytes).
        :param datetime created_at: The date and time that the disk was created.
        :param str href: The URL for this disk.
        :param str id: The unique identifier for this disk.
        :param List[InstanceDiskReference] instance_disks: Instance disks that are
               on this dedicated host disk.
        :param str interface_type: The disk interface used for attaching the disk
               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 resource on
               which the unexpected property value was encountered.
        :param str name: The user-defined or system-provided name for this disk.
        :param bool provisionable: Indicates whether this dedicated host disk is
               available for instance disk creation.
        :param str resource_type: The type of resource referenced.
        :param int size: The size of the disk in GB (gigabytes).
        :param List[str] supported_instance_interface_types: The instance disk
               interfaces supported for this dedicated host disk.
        :param str lifecycle_state: (optional) The lifecycle state of this
               dedicated host disk.
        """
        self.available = available
        self.created_at = created_at
        self.href = href
        self.id = id
        self.instance_disks = instance_disks
        self.interface_type = interface_type
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.provisionable = provisionable
        self.resource_type = resource_type
        self.size = size
        self.supported_instance_interface_types = supported_instance_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDisk':
        """Initialize a DedicatedHostDisk object from a json dictionary."""
        args = {}
        if 'available' in _dict:
            args['available'] = _dict.get('available')
        else:
            raise ValueError(
                'Required property \'available\' not present in DedicatedHostDisk 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 DedicatedHostDisk JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostDisk JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DedicatedHostDisk JSON'
            )
        if 'instance_disks' in _dict:
            args['instance_disks'] = [
                InstanceDiskReference.from_dict(x)
                for x in _dict.get('instance_disks')
            ]
        else:
            raise ValueError(
                'Required property \'instance_disks\' not present in DedicatedHostDisk JSON'
            )
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError(
                'Required property \'interface_type\' not present in DedicatedHostDisk JSON'
            )
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostDisk JSON'
            )
        if 'provisionable' in _dict:
            args['provisionable'] = _dict.get('provisionable')
        else:
            raise ValueError(
                'Required property \'provisionable\' not present in DedicatedHostDisk JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in DedicatedHostDisk JSON'
            )
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError(
                'Required property \'size\' not present in DedicatedHostDisk JSON'
            )
        if 'supported_instance_interface_types' in _dict:
            args['supported_instance_interface_types'] = _dict.get(
                'supported_instance_interface_types')
        else:
            raise ValueError(
                'Required property \'supported_instance_interface_types\' not present in DedicatedHostDisk JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'available') and self.available is not None:
            _dict['available'] = self.available
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance_disks') and self.instance_disks is not None:
            _dict['instance_disks'] = [x.to_dict() for x in self.instance_disks]
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'provisionable') and self.provisionable is not None:
            _dict['provisionable'] = self.provisionable
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        if hasattr(self, 'supported_instance_interface_types'
                  ) and self.supported_instance_interface_types is not None:
            _dict[
                'supported_instance_interface_types'] = self.supported_instance_interface_types
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        The disk interface used for attaching the disk
        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 resource on which the unexpected
        property value was encountered.
        """
        NVME = 'nvme'

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of this dedicated host disk.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        DEDICATED_HOST_DISK = 'dedicated_host_disk'

    class SupportedInstanceInterfaceTypesEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        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 resource on which the unexpected
        property value was encountered.
        """
        VIRTIO_BLK = 'virtio_blk'
        NVME = 'nvme'


class DedicatedHostDiskCollection():
    """
    DedicatedHostDiskCollection.

    :attr List[DedicatedHostDisk] disks: Collection of the dedicated host's disks.
    """

    def __init__(self, disks: List['DedicatedHostDisk']) -> None:
        """
        Initialize a DedicatedHostDiskCollection object.

        :param List[DedicatedHostDisk] disks: Collection of the dedicated host's
               disks.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDiskCollection':
        """Initialize a DedicatedHostDiskCollection object from a json dictionary."""
        args = {}
        if 'disks' in _dict:
            args['disks'] = [
                DedicatedHostDisk.from_dict(x) for x in _dict.get('disks')
            ]
        else:
            raise ValueError(
                'Required property \'disks\' not present in DedicatedHostDiskCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostDiskCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'disks') and self.disks is not None:
            _dict['disks'] = [x.to_dict() for x in self.disks]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostDiskCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostDiskCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostDiskCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostDiskPatch():
    """
    DedicatedHostDiskPatch.

    :attr str name: (optional) The user-defined name for this disk.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a DedicatedHostDiskPatch object.

        :param str name: (optional) The user-defined name for this disk.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDiskPatch':
        """Initialize a DedicatedHostDiskPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostDiskPatch object from 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 DedicatedHostDiskPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostDiskPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostDiskPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroup():
    """
    DedicatedHostGroup.

    :attr str class_: The dedicated host profile class for hosts in this group.
    :attr datetime created_at: The date and time that the dedicated host group was
          created.
    :attr str crn: The CRN for this dedicated host group.
    :attr List[DedicatedHostReference] dedicated_hosts: The dedicated hosts that are
          in this dedicated host group.
    :attr str family: The dedicated host profile family for hosts in this group.
    :attr str href: The URL for this dedicated host group.
    :attr str id: The unique identifier for this dedicated host group.
    :attr str name: The unique user-defined name for this dedicated host group. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr ResourceGroupReference resource_group: The resource group for this
          dedicated host group.
    :attr str resource_type: The type of resource referenced.
    :attr List[InstanceProfileReference] supported_instance_profiles: Array of
          instance profiles that can be used by instances placed on this dedicated host
          group.
    :attr ZoneReference zone: The zone this dedicated host group resides in.
    """

    def __init__(self, class_: str, created_at: datetime, crn: str,
                 dedicated_hosts: List['DedicatedHostReference'], family: str,
                 href: str, id: str, name: str,
                 resource_group: 'ResourceGroupReference', resource_type: str,
                 supported_instance_profiles: List['InstanceProfileReference'],
                 zone: 'ZoneReference') -> None:
        """
        Initialize a DedicatedHostGroup object.

        :param str class_: The dedicated host profile class for hosts in this
               group.
        :param datetime created_at: The date and time that the dedicated host group
               was created.
        :param str crn: The CRN for this dedicated host group.
        :param List[DedicatedHostReference] dedicated_hosts: The dedicated hosts
               that are in this dedicated host group.
        :param str family: The dedicated host profile family for hosts in this
               group.
        :param str href: The URL for this dedicated host group.
        :param str id: The unique identifier for this dedicated host group.
        :param str name: The unique user-defined name for this dedicated host
               group. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param ResourceGroupReference resource_group: The resource group for this
               dedicated host group.
        :param str resource_type: The type of resource referenced.
        :param List[InstanceProfileReference] supported_instance_profiles: Array of
               instance profiles that can be used by instances placed on this dedicated
               host group.
        :param ZoneReference zone: The zone this dedicated host group resides in.
        """
        self.class_ = class_
        self.created_at = created_at
        self.crn = crn
        self.dedicated_hosts = dedicated_hosts
        self.family = family
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.supported_instance_profiles = supported_instance_profiles
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroup':
        """Initialize a DedicatedHostGroup object from a json dictionary."""
        args = {}
        if 'class' in _dict:
            args['class_'] = _dict.get('class')
        else:
            raise ValueError(
                'Required property \'class\' not present in DedicatedHostGroup 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 DedicatedHostGroup JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DedicatedHostGroup JSON'
            )
        if 'dedicated_hosts' in _dict:
            args['dedicated_hosts'] = [
                DedicatedHostReference.from_dict(x)
                for x in _dict.get('dedicated_hosts')
            ]
        else:
            raise ValueError(
                'Required property \'dedicated_hosts\' not present in DedicatedHostGroup JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' not present in DedicatedHostGroup JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostGroup JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DedicatedHostGroup JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostGroup 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 DedicatedHostGroup JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in DedicatedHostGroup JSON'
            )
        if 'supported_instance_profiles' in _dict:
            args['supported_instance_profiles'] = [
                InstanceProfileReference.from_dict(x)
                for x in _dict.get('supported_instance_profiles')
            ]
        else:
            raise ValueError(
                'Required property \'supported_instance_profiles\' not present in DedicatedHostGroup JSON'
            )
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError(
                'Required property \'zone\' not present in DedicatedHostGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'class_') and self.class_ is not None:
            _dict['class'] = self.class_
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self,
                   'dedicated_hosts') and self.dedicated_hosts is not None:
            _dict['dedicated_hosts'] = [
                x.to_dict() for x in self.dedicated_hosts
            ]
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'supported_instance_profiles'
                  ) and self.supported_instance_profiles is not None:
            _dict['supported_instance_profiles'] = [
                x.to_dict() for x in self.supported_instance_profiles
            ]
        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 DedicatedHostGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class FamilyEnum(str, Enum):
        """
        The dedicated host profile family for hosts in this group.
        """
        MEMORY = 'memory'
        BALANCED = 'balanced'
        COMPUTE = 'compute'

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        DEDICATED_HOST_GROUP = 'dedicated_host_group'


class DedicatedHostGroupCollection():
    """
    DedicatedHostGroupCollection.

    :attr DedicatedHostGroupCollectionFirst first: A link to the first page of
          resources.
    :attr List[DedicatedHostGroup] groups: Collection of dedicated host groups.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr DedicatedHostGroupCollectionNext next: (optional) A link to the next page
          of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'DedicatedHostGroupCollectionFirst',
                 groups: List['DedicatedHostGroup'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'DedicatedHostGroupCollectionNext' = None) -> None:
        """
        Initialize a DedicatedHostGroupCollection object.

        :param DedicatedHostGroupCollectionFirst first: A link to the first page of
               resources.
        :param List[DedicatedHostGroup] groups: Collection of dedicated host
               groups.
        :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 DedicatedHostGroupCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.groups = groups
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupCollection':
        """Initialize a DedicatedHostGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = DedicatedHostGroupCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in DedicatedHostGroupCollection JSON'
            )
        if 'groups' in _dict:
            args['groups'] = [
                DedicatedHostGroup.from_dict(x) for x in _dict.get('groups')
            ]
        else:
            raise ValueError(
                'Required property \'groups\' not present in DedicatedHostGroupCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in DedicatedHostGroupCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = DedicatedHostGroupCollectionNext.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 DedicatedHostGroupCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupCollection object from 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, 'groups') and self.groups is not None:
            _dict['groups'] = [x.to_dict() for x in self.groups]
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostGroupCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupCollectionFirst':
        """Initialize a DedicatedHostGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostGroupCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupCollectionFirst object from 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 DedicatedHostGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostGroupCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupCollectionNext':
        """Initialize a DedicatedHostGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostGroupCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupCollectionNext object from 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 DedicatedHostGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentity():
    """
    Identifies a dedicated host group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a DedicatedHostGroupIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'DedicatedHostGroupIdentityById',
                'DedicatedHostGroupIdentityByCRN',
                'DedicatedHostGroupIdentityByHref'
            ]))
        raise Exception(msg)


class DedicatedHostGroupPatch():
    """
    DedicatedHostGroupPatch.

    :attr str name: (optional) The unique user-defined name for this dedicated host
          group. If unspecified, the name will be a hyphenated list of randomly-selected
          words.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a DedicatedHostGroupPatch object.

        :param str name: (optional) The unique user-defined name for this dedicated
               host group. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupPatch':
        """Initialize a DedicatedHostGroupPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupPatch object from 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 DedicatedHostGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupPrototypeDedicatedHostByZoneContext():
    """
    DedicatedHostGroupPrototypeDedicatedHostByZoneContext.

    :attr str name: (optional) The unique user-defined name for this dedicated host
          group. 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 host's resource group is used.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a DedicatedHostGroupPrototypeDedicatedHostByZoneContext object.

        :param str name: (optional) The unique user-defined name for this dedicated
               host group. 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 host's resource group is used.
        """
        self.name = name
        self.resource_group = resource_group

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext':
        """Initialize a DedicatedHostGroupPrototypeDedicatedHostByZoneContext 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 DedicatedHostGroupPrototypeDedicatedHostByZoneContext object from 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 DedicatedHostGroupPrototypeDedicatedHostByZoneContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupReference():
    """
    DedicatedHostGroupReference.

    :attr str crn: The CRN for this dedicated host group.
    :attr DedicatedHostGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this dedicated host group.
    :attr str id: The unique identifier for this dedicated host group.
    :attr str name: The unique user-defined name for this dedicated host group. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str resource_type: The type of resource referenced.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'DedicatedHostGroupReferenceDeleted' = None) -> None:
        """
        Initialize a DedicatedHostGroupReference object.

        :param str crn: The CRN for this dedicated host group.
        :param str href: The URL for this dedicated host group.
        :param str id: The unique identifier for this dedicated host group.
        :param str name: The unique user-defined name for this dedicated host
               group. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str resource_type: The type of resource referenced.
        :param DedicatedHostGroupReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupReference':
        """Initialize a DedicatedHostGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DedicatedHostGroupReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = DedicatedHostGroupReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostGroupReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DedicatedHostGroupReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostGroupReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in DedicatedHostGroupReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupReference object from 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
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 DedicatedHostGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        DEDICATED_HOST_GROUP = 'dedicated_host_group'


class DedicatedHostGroupReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a DedicatedHostGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupReferenceDeleted':
        """Initialize a DedicatedHostGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in DedicatedHostGroupReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostPatch():
    """
    DedicatedHostPatch.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The unique user-defined name for this dedicated host.
          If unspecified, the name will be a hyphenated list of randomly-selected words.
    """

    def __init__(self,
                 *,
                 instance_placement_enabled: bool = None,
                 name: str = None) -> None:
        """
        Initialize a DedicatedHostPatch object.

        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The unique user-defined name for this dedicated
               host. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        """
        self.instance_placement_enabled = instance_placement_enabled
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostPatch':
        """Initialize a DedicatedHostPatch object from a json dictionary."""
        args = {}
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get(
                'instance_placement_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance_placement_enabled'
                  ) and self.instance_placement_enabled is not None:
            _dict[
                'instance_placement_enabled'] = self.instance_placement_enabled
        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 DedicatedHostPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfile():
    """
    DedicatedHostProfile.

    :attr str class_: The product class this dedicated host profile belongs to.
    :attr List[DedicatedHostProfileDisk] disks: Collection of the dedicated host
          profile's disks.
    :attr str family: The product family this dedicated host profile belongs to
          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 resource on which the unexpected
          property value was encountered.
    :attr str href: The URL for this dedicated host.
    :attr DedicatedHostProfileMemory memory:
    :attr str name: The globally unique name for this dedicated host profile.
    :attr DedicatedHostProfileSocket socket_count:
    :attr List[InstanceProfileReference] supported_instance_profiles: Array of
          instance profiles that can be used by instances placed on dedicated hosts with
          this profile.
    :attr DedicatedHostProfileVCPUArchitecture vcpu_architecture:
    :attr DedicatedHostProfileVCPU vcpu_count:
    """

    def __init__(self, class_: str, disks: List['DedicatedHostProfileDisk'],
                 family: str, href: str, memory: 'DedicatedHostProfileMemory',
                 name: str, socket_count: 'DedicatedHostProfileSocket',
                 supported_instance_profiles: List['InstanceProfileReference'],
                 vcpu_architecture: 'DedicatedHostProfileVCPUArchitecture',
                 vcpu_count: 'DedicatedHostProfileVCPU') -> None:
        """
        Initialize a DedicatedHostProfile object.

        :param str class_: The product class this dedicated host profile belongs
               to.
        :param List[DedicatedHostProfileDisk] disks: Collection of the dedicated
               host profile's disks.
        :param str family: The product family this dedicated host profile belongs
               to
               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 resource on
               which the unexpected property value was encountered.
        :param str href: The URL for this dedicated host.
        :param DedicatedHostProfileMemory memory:
        :param str name: The globally unique name for this dedicated host profile.
        :param DedicatedHostProfileSocket socket_count:
        :param List[InstanceProfileReference] supported_instance_profiles: Array of
               instance profiles that can be used by instances placed on dedicated hosts
               with this profile.
        :param DedicatedHostProfileVCPUArchitecture vcpu_architecture:
        :param DedicatedHostProfileVCPU vcpu_count:
        """
        self.class_ = class_
        self.disks = disks
        self.family = family
        self.href = href
        self.memory = memory
        self.name = name
        self.socket_count = socket_count
        self.supported_instance_profiles = supported_instance_profiles
        self.vcpu_architecture = vcpu_architecture
        self.vcpu_count = vcpu_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfile':
        """Initialize a DedicatedHostProfile object from a json dictionary."""
        args = {}
        if 'class' in _dict:
            args['class_'] = _dict.get('class')
        else:
            raise ValueError(
                'Required property \'class\' not present in DedicatedHostProfile JSON'
            )
        if 'disks' in _dict:
            args['disks'] = [
                DedicatedHostProfileDisk.from_dict(x)
                for x in _dict.get('disks')
            ]
        else:
            raise ValueError(
                'Required property \'disks\' not present in DedicatedHostProfile JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' not present in DedicatedHostProfile JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostProfile JSON'
            )
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError(
                'Required property \'memory\' not present in DedicatedHostProfile JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostProfile JSON'
            )
        if 'socket_count' in _dict:
            args['socket_count'] = _dict.get('socket_count')
        else:
            raise ValueError(
                'Required property \'socket_count\' not present in DedicatedHostProfile JSON'
            )
        if 'supported_instance_profiles' in _dict:
            args['supported_instance_profiles'] = [
                InstanceProfileReference.from_dict(x)
                for x in _dict.get('supported_instance_profiles')
            ]
        else:
            raise ValueError(
                'Required property \'supported_instance_profiles\' not present in DedicatedHostProfile JSON'
            )
        if 'vcpu_architecture' in _dict:
            args[
                'vcpu_architecture'] = DedicatedHostProfileVCPUArchitecture.from_dict(
                    _dict.get('vcpu_architecture'))
        else:
            raise ValueError(
                'Required property \'vcpu_architecture\' not present in DedicatedHostProfile JSON'
            )
        if 'vcpu_count' in _dict:
            args['vcpu_count'] = _dict.get('vcpu_count')
        else:
            raise ValueError(
                'Required property \'vcpu_count\' not present in DedicatedHostProfile JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'class_') and self.class_ is not None:
            _dict['class'] = self.class_
        if hasattr(self, 'disks') and self.disks is not None:
            _dict['disks'] = [x.to_dict() for x in self.disks]
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'socket_count') and self.socket_count is not None:
            if isinstance(self.socket_count, dict):
                _dict['socket_count'] = self.socket_count
            else:
                _dict['socket_count'] = self.socket_count.to_dict()
        if hasattr(self, 'supported_instance_profiles'
                  ) and self.supported_instance_profiles is not None:
            _dict['supported_instance_profiles'] = [
                x.to_dict() for x in self.supported_instance_profiles
            ]
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class FamilyEnum(str, Enum):
        """
        The product family this dedicated host profile belongs to
        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 resource on which the unexpected
        property value was encountered.
        """
        MEMORY = 'memory'
        BALANCED = 'balanced'
        COMPUTE = 'compute'


class DedicatedHostProfileCollection():
    """
    DedicatedHostProfileCollection.

    :attr DedicatedHostProfileCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr DedicatedHostProfileCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr List[DedicatedHostProfile] profiles: Collection of dedicated host
          profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'DedicatedHostProfileCollectionFirst',
                 limit: int,
                 profiles: List['DedicatedHostProfile'],
                 total_count: int,
                 *,
                 next: 'DedicatedHostProfileCollectionNext' = None) -> None:
        """
        Initialize a DedicatedHostProfileCollection object.

        :param DedicatedHostProfileCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[DedicatedHostProfile] profiles: Collection of dedicated host
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param DedicatedHostProfileCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.profiles = profiles
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileCollection':
        """Initialize a DedicatedHostProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = DedicatedHostProfileCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in DedicatedHostProfileCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in DedicatedHostProfileCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = DedicatedHostProfileCollectionNext.from_dict(
                _dict.get('next'))
        if 'profiles' in _dict:
            args['profiles'] = [
                DedicatedHostProfile.from_dict(x) for x in _dict.get('profiles')
            ]
        else:
            raise ValueError(
                'Required property \'profiles\' not present in DedicatedHostProfileCollection JSON'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in DedicatedHostProfileCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileCollection object from 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, 'profiles') and self.profiles is not None:
            _dict['profiles'] = [x.to_dict() for x in self.profiles]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 DedicatedHostProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostProfileCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileCollectionFirst':
        """Initialize a DedicatedHostProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostProfileCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileCollectionFirst object from 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 DedicatedHostProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostProfileCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileCollectionNext':
        """Initialize a DedicatedHostProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostProfileCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileCollectionNext object from 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 DedicatedHostProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileDisk():
    """
    Disks provided by this profile.

    :attr DedicatedHostProfileDiskInterface interface_type:
    :attr DedicatedHostProfileDiskQuantity quantity: The number of disks of this
          type for a dedicated host with this profile.
    :attr DedicatedHostProfileDiskSize size: The size of the disk in GB (gigabytes).
    :attr DedicatedHostProfileDiskSupportedInterfaces
          supported_instance_interface_types:
    """

    def __init__(
        self, interface_type: 'DedicatedHostProfileDiskInterface',
        quantity: 'DedicatedHostProfileDiskQuantity',
        size: 'DedicatedHostProfileDiskSize',
        supported_instance_interface_types:
        'DedicatedHostProfileDiskSupportedInterfaces'
    ) -> None:
        """
        Initialize a DedicatedHostProfileDisk object.

        :param DedicatedHostProfileDiskInterface interface_type:
        :param DedicatedHostProfileDiskQuantity quantity: The number of disks of
               this type for a dedicated host with this profile.
        :param DedicatedHostProfileDiskSize size: The size of the disk in GB
               (gigabytes).
        :param DedicatedHostProfileDiskSupportedInterfaces
               supported_instance_interface_types:
        """
        self.interface_type = interface_type
        self.quantity = quantity
        self.size = size
        self.supported_instance_interface_types = supported_instance_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDisk':
        """Initialize a DedicatedHostProfileDisk object from a json dictionary."""
        args = {}
        if 'interface_type' in _dict:
            args[
                'interface_type'] = DedicatedHostProfileDiskInterface.from_dict(
                    _dict.get('interface_type'))
        else:
            raise ValueError(
                'Required property \'interface_type\' not present in DedicatedHostProfileDisk JSON'
            )
        if 'quantity' in _dict:
            args['quantity'] = DedicatedHostProfileDiskQuantity.from_dict(
                _dict.get('quantity'))
        else:
            raise ValueError(
                'Required property \'quantity\' not present in DedicatedHostProfileDisk JSON'
            )
        if 'size' in _dict:
            args['size'] = DedicatedHostProfileDiskSize.from_dict(
                _dict.get('size'))
        else:
            raise ValueError(
                'Required property \'size\' not present in DedicatedHostProfileDisk JSON'
            )
        if 'supported_instance_interface_types' in _dict:
            args[
                'supported_instance_interface_types'] = DedicatedHostProfileDiskSupportedInterfaces.from_dict(
                    _dict.get('supported_instance_interface_types'))
        else:
            raise ValueError(
                'Required property \'supported_instance_interface_types\' not present in DedicatedHostProfileDisk JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type.to_dict()
        if hasattr(self, 'quantity') and self.quantity is not None:
            _dict['quantity'] = self.quantity.to_dict()
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size.to_dict()
        if hasattr(self, 'supported_instance_interface_types'
                  ) and self.supported_instance_interface_types is not None:
            _dict[
                'supported_instance_interface_types'] = self.supported_instance_interface_types.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 DedicatedHostProfileDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileDiskInterface():
    """
    DedicatedHostProfileDiskInterface.

    :attr str type: The type for this profile field.
    :attr str value: The interface of the disk for a dedicated host with this
          profile
          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 resource on which the unexpected
          property value was encountered.
    """

    def __init__(self, type: str, value: str) -> None:
        """
        Initialize a DedicatedHostProfileDiskInterface object.

        :param str type: The type for this profile field.
        :param str value: The interface of the disk for a dedicated host with this
               profile
               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 resource on
               which the unexpected property value was encountered.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskInterface':
        """Initialize a DedicatedHostProfileDiskInterface object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileDiskInterface JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileDiskInterface JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskInterface object from 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 DedicatedHostProfileDiskInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskInterface') -> 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 ValueEnum(str, Enum):
        """
        The interface of the disk for a dedicated host with this profile
        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 resource on which the unexpected
        property value was encountered.
        """
        NVME = 'nvme'


class DedicatedHostProfileDiskQuantity():
    """
    The number of disks of this type for a dedicated host 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 DedicatedHostProfileDiskQuantity object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskQuantity':
        """Initialize a DedicatedHostProfileDiskQuantity object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileDiskQuantity JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileDiskQuantity JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskQuantity object from 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 DedicatedHostProfileDiskQuantity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskQuantity') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskQuantity') -> 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 DedicatedHostProfileDiskSize():
    """
    The size of the disk in GB (gigabytes).

    :attr str type: The type for this profile field.
    :attr int value: The size of the disk in GB (gigabytes).
    """

    def __init__(self, type: str, value: int) -> None:
        """
        Initialize a DedicatedHostProfileDiskSize object.

        :param str type: The type for this profile field.
        :param int value: The size of the disk in GB (gigabytes).
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskSize':
        """Initialize a DedicatedHostProfileDiskSize object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileDiskSize JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileDiskSize JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskSize object from 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 DedicatedHostProfileDiskSize object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskSize') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskSize') -> 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 DedicatedHostProfileDiskSupportedInterfaces():
    """
    DedicatedHostProfileDiskSupportedInterfaces.

    :attr str type: The type for this profile field.
    :attr List[str] value: The instance disk interfaces supported for a dedicated
          host with this profile.
    """

    def __init__(self, type: str, value: List[str]) -> None:
        """
        Initialize a DedicatedHostProfileDiskSupportedInterfaces object.

        :param str type: The type for this profile field.
        :param List[str] value: The instance disk interfaces supported for a
               dedicated host with this profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'DedicatedHostProfileDiskSupportedInterfaces':
        """Initialize a DedicatedHostProfileDiskSupportedInterfaces object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileDiskSupportedInterfaces JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileDiskSupportedInterfaces JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskSupportedInterfaces object from 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 DedicatedHostProfileDiskSupportedInterfaces object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'DedicatedHostProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'DedicatedHostProfileDiskSupportedInterfaces') -> 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 ValueEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        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 resource on which the unexpected
        property value was encountered.
        """
        VIRTIO_BLK = 'virtio_blk'
        NVME = 'nvme'


class DedicatedHostProfileIdentity():
    """
    Identifies a dedicated host profile by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a DedicatedHostProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'DedicatedHostProfileIdentityByName',
                'DedicatedHostProfileIdentityByHref'
            ]))
        raise Exception(msg)


class DedicatedHostProfileMemory():
    """
    DedicatedHostProfileMemory.

    """

    def __init__(self) -> None:
        """
        Initialize a DedicatedHostProfileMemory object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'DedicatedHostProfileMemoryFixed',
                'DedicatedHostProfileMemoryRange',
                'DedicatedHostProfileMemoryEnum',
                'DedicatedHostProfileMemoryDependent'
            ]))
        raise Exception(msg)


class DedicatedHostProfileReference():
    """
    DedicatedHostProfileReference.

    :attr str href: The URL for this dedicated host.
    :attr str name: The globally unique name for this dedicated host profile.
    """

    def __init__(self, href: str, name: str) -> None:
        """
        Initialize a DedicatedHostProfileReference object.

        :param str href: The URL for this dedicated host.
        :param str name: The globally unique name for this dedicated host profile.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileReference':
        """Initialize a DedicatedHostProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostProfileReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostProfileReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileReference object from 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
        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 DedicatedHostProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileSocket():
    """
    DedicatedHostProfileSocket.

    """

    def __init__(self) -> None:
        """
        Initialize a DedicatedHostProfileSocket object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'DedicatedHostProfileSocketFixed',
                'DedicatedHostProfileSocketRange',
                'DedicatedHostProfileSocketEnum',
                'DedicatedHostProfileSocketDependent'
            ]))
        raise Exception(msg)


class DedicatedHostProfileVCPU():
    """
    DedicatedHostProfileVCPU.

    """

    def __init__(self) -> None:
        """
        Initialize a DedicatedHostProfileVCPU object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'DedicatedHostProfileVCPUFixed',
                'DedicatedHostProfileVCPURange', 'DedicatedHostProfileVCPUEnum',
                'DedicatedHostProfileVCPUDependent'
            ]))
        raise Exception(msg)


class DedicatedHostProfileVCPUArchitecture():
    """
    DedicatedHostProfileVCPUArchitecture.

    :attr str type: The type for this profile field.
    :attr str value: The VCPU architecture for a dedicated host with this profile.
    """

    def __init__(self, type: str, value: str) -> None:
        """
        Initialize a DedicatedHostProfileVCPUArchitecture object.

        :param str type: The type for this profile field.
        :param str value: The VCPU architecture for a dedicated host with this
               profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUArchitecture':
        """Initialize a DedicatedHostProfileVCPUArchitecture object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileVCPUArchitecture JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileVCPUArchitecture JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUArchitecture object from 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 DedicatedHostProfileVCPUArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUArchitecture') -> 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 DedicatedHostPrototype():
    """
    DedicatedHostPrototype.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The unique user-defined name for this dedicated host.
          If unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileIdentity profile: The profile to use for this
          dedicated host.
    :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,
                 profile: 'DedicatedHostProfileIdentity',
                 *,
                 instance_placement_enabled: bool = None,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a DedicatedHostPrototype object.

        :param DedicatedHostProfileIdentity profile: The profile to use for this
               dedicated host.
        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The unique user-defined name for this dedicated
               host. 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([
                'DedicatedHostPrototypeDedicatedHostByGroup',
                'DedicatedHostPrototypeDedicatedHostByZone'
            ]))
        raise Exception(msg)


class DedicatedHostReference():
    """
    DedicatedHostReference.

    :attr str crn: The CRN for this dedicated host.
    :attr DedicatedHostReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this dedicated host.
    :attr str id: The unique identifier for this dedicated host.
    :attr str name: The unique user-defined name for this dedicated host. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str resource_type: The type of resource referenced.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'DedicatedHostReferenceDeleted' = None) -> None:
        """
        Initialize a DedicatedHostReference object.

        :param str crn: The CRN for this dedicated host.
        :param str href: The URL for this dedicated host.
        :param str id: The unique identifier for this dedicated host.
        :param str name: The unique user-defined name for this dedicated host. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param str resource_type: The type of resource referenced.
        :param DedicatedHostReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostReference':
        """Initialize a DedicatedHostReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DedicatedHostReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = DedicatedHostReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DedicatedHostReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in DedicatedHostReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostReference object from 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
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 DedicatedHostReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        DEDICATED_HOST = 'dedicated_host'


class DedicatedHostReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a DedicatedHostReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostReferenceDeleted':
        """Initialize a DedicatedHostReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in DedicatedHostReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DefaultNetworkACL():
    """
    DefaultNetworkACL.

    :attr datetime created_at: The date and time that the network ACL was created.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str id: The unique identifier 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 ResourceGroupReference resource_group: The resource group for the default
          network ACL for a VPC. Set to the VPC's
          resource group at creation.
    :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.
    :attr VPCReference vpc: The VPC this network ACL is a part of.
    """

    def __init__(self, created_at: datetime, crn: str, href: str, id: str,
                 name: str, resource_group: 'ResourceGroupReference',
                 rules: List['NetworkACLRuleItem'],
                 subnets: List['SubnetReference'], vpc: 'VPCReference') -> None:
        """
        Initialize a DefaultNetworkACL object.

        :param datetime created_at: The date and time that the network ACL was
               created.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str id: The unique identifier 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 ResourceGroupReference resource_group: The resource group for the
               default network ACL for a VPC. Set to the VPC's
               resource group at creation.
        :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.
        :param VPCReference vpc: The VPC this network ACL is a part of.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.subnets = subnets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultNetworkACL':
        """Initialize a DefaultNetworkACL object from a json dictionary."""
        args = {}
        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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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 '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'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, '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, 'resource_group') and self.resource_group is not None:
            _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]
        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 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 DefaultRoutingTable():
    """
    DefaultRoutingTable.

    :attr datetime created_at: The date and time that this routing table was
          created.
    :attr str href: The URL for this routing table.
    :attr str id: The unique identifier for this routing table.
    :attr bool is_default: Indicates whether this is the default routing table for
          this VPC.
    :attr str lifecycle_state: The lifecycle state of the routing table.
    :attr str name: The name of the default routing table created for this VPC. The
          name will be a hyphenated list of randomly-selected words at creation, but may
          be user-specified with a subsequent request.
    :attr str resource_type: The resource type.
    :attr bool route_direct_link_ingress: Indicates whether this routing table is
          used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr bool route_transit_gateway_ingress: Indicates whether this routing table
          is used to route traffic that originates from from [Transit
          Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr bool route_vpc_zone_ingress: Indicates whether this routing table is used
          to route traffic that originates from subnets in other zones in this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr List[RouteReference] routes: The routes for the default routing table for
          this VPC. The table is created with no routes, but routes may be added, changed,
          or removed with a subsequent request.
    :attr List[SubnetReference] subnets: The subnets to which this routing table is
          attached.
    """

    def __init__(self, created_at: datetime, href: str, id: str,
                 is_default: bool, lifecycle_state: str, name: str,
                 resource_type: str, route_direct_link_ingress: bool,
                 route_transit_gateway_ingress: bool,
                 route_vpc_zone_ingress: bool, routes: List['RouteReference'],
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a DefaultRoutingTable object.

        :param datetime created_at: The date and time that this routing table was
               created.
        :param str href: The URL for this routing table.
        :param str id: The unique identifier for this routing table.
        :param bool is_default: Indicates whether this is the default routing table
               for this VPC.
        :param str lifecycle_state: The lifecycle state of the routing table.
        :param str name: The name of the default routing table created for this
               VPC. The name will be a hyphenated list of randomly-selected words at
               creation, but may be user-specified with a subsequent request.
        :param str resource_type: The resource type.
        :param bool route_direct_link_ingress: Indicates whether this routing table
               is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param bool route_transit_gateway_ingress: Indicates whether this routing
               table is used to route traffic that originates from from [Transit
               Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param bool route_vpc_zone_ingress: Indicates whether this routing table is
               used to route traffic that originates from subnets in other zones in this
               VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param List[RouteReference] routes: The routes for the default routing
               table for this VPC. The table is created with no routes, but routes may be
               added, changed, or removed with a subsequent request.
        :param List[SubnetReference] subnets: The subnets to which this routing
               table is attached.
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.is_default = is_default
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type
        self.route_direct_link_ingress = route_direct_link_ingress
        self.route_transit_gateway_ingress = route_transit_gateway_ingress
        self.route_vpc_zone_ingress = route_vpc_zone_ingress
        self.routes = routes
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultRoutingTable':
        """Initialize a DefaultRoutingTable object from a json dictionary."""
        args = {}
        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 DefaultRoutingTable JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DefaultRoutingTable JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DefaultRoutingTable JSON'
            )
        if 'is_default' in _dict:
            args['is_default'] = _dict.get('is_default')
        else:
            raise ValueError(
                'Required property \'is_default\' not present in DefaultRoutingTable JSON'
            )
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' not present in DefaultRoutingTable JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DefaultRoutingTable JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in DefaultRoutingTable JSON'
            )
        if 'route_direct_link_ingress' in _dict:
            args['route_direct_link_ingress'] = _dict.get(
                'route_direct_link_ingress')
        else:
            raise ValueError(
                'Required property \'route_direct_link_ingress\' not present in DefaultRoutingTable JSON'
            )
        if 'route_transit_gateway_ingress' in _dict:
            args['route_transit_gateway_ingress'] = _dict.get(
                'route_transit_gateway_ingress')
        else:
            raise ValueError(
                'Required property \'route_transit_gateway_ingress\' not present in DefaultRoutingTable JSON'
            )
        if 'route_vpc_zone_ingress' in _dict:
            args['route_vpc_zone_ingress'] = _dict.get('route_vpc_zone_ingress')
        else:
            raise ValueError(
                'Required property \'route_vpc_zone_ingress\' not present in DefaultRoutingTable JSON'
            )
        if 'routes' in _dict:
            args['routes'] = [
                RouteReference.from_dict(x) for x in _dict.get('routes')
            ]
        else:
            raise ValueError(
                'Required property \'routes\' not present in DefaultRoutingTable 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 DefaultRoutingTable JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DefaultRoutingTable object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        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, 'route_direct_link_ingress'
                  ) and self.route_direct_link_ingress is not None:
            _dict['route_direct_link_ingress'] = self.route_direct_link_ingress
        if hasattr(self, 'route_transit_gateway_ingress'
                  ) and self.route_transit_gateway_ingress is not None:
            _dict[
                'route_transit_gateway_ingress'] = self.route_transit_gateway_ingress
        if hasattr(self, 'route_vpc_zone_ingress'
                  ) and self.route_vpc_zone_ingress is not None:
            _dict['route_vpc_zone_ingress'] = self.route_vpc_zone_ingress
        if hasattr(self, 'routes') and self.routes is not None:
            _dict['routes'] = [x.to_dict() for x in self.routes]
        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 DefaultRoutingTable object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DefaultRoutingTable') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DefaultRoutingTable') -> 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 routing table.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        ROUTING_TABLE = 'routing_table'


class DefaultSecurityGroup():
    """
    DefaultSecurityGroup.

    :attr datetime created_at: The date and time that this security group was
          created.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :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 ResourceGroupReference resource_group: The resource group for this
          security group.
    :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 VPCReference vpc: The VPC this security group is a part of.
    """

    def __init__(self, created_at: datetime, crn: str, href: str, id: str,
                 name: str, resource_group: 'ResourceGroupReference',
                 rules: List['SecurityGroupRule'], vpc: 'VPCReference') -> None:
        """
        Initialize a DefaultSecurityGroup object.

        :param datetime created_at: The date and time that this security group was
               created.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :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 ResourceGroupReference resource_group: The resource group for this
               security group.
        :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 VPCReference vpc: The VPC this security group is a part of.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultSecurityGroup':
        """Initialize a DefaultSecurityGroup object from a json dictionary."""
        args = {}
        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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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 '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 '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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, '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, 'resource_group') and self.resource_group is not None:
            _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]
        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 EndpointGateway():
    """
    EndpointGateway.

    :attr datetime created_at: The date and time that the endpoint gateway was
          created.
    :attr str crn: The CRN for this endpoint gateway.
    :attr str health_state: The health of this resource.
          - `ok`: Healthy
          - `degraded`: Suffering from compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The URL for this endpoint gateway.
    :attr str id: The unique identifier for this endpoint gateway.
    :attr List[ReservedIPReference] ips: Collection of reserved IPs bound to an
          endpoint gateway.
    :attr str lifecycle_state: The lifecycle state of the endpoint gateway.
    :attr str name: The unique user-defined name for this endpoint gateway.
    :attr ResourceGroupReference resource_group: The resource group for this
          endpoint gateway.
    :attr str resource_type: The type of resource referenced.
    :attr str service_endpoint: (optional) The fully qualified domain name for the
          target service.
    :attr List[str] service_endpoints: Collection of fully qualified domain names
          for the target service.
    :attr EndpointGatewayTarget target: The target for this endpoint gateway.
    :attr VPCReference vpc: The VPC this endpoint gateway is serving.
    """

    def __init__(self,
                 created_at: datetime,
                 crn: str,
                 health_state: str,
                 href: str,
                 id: str,
                 ips: List['ReservedIPReference'],
                 lifecycle_state: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 resource_type: str,
                 service_endpoints: List[str],
                 target: 'EndpointGatewayTarget',
                 vpc: 'VPCReference',
                 *,
                 service_endpoint: str = None) -> None:
        """
        Initialize a EndpointGateway object.

        :param datetime created_at: The date and time that the endpoint gateway was
               created.
        :param str crn: The CRN for this endpoint gateway.
        :param str health_state: The health of this resource.
               - `ok`: Healthy
               - `degraded`: Suffering from compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The URL for this endpoint gateway.
        :param str id: The unique identifier for this endpoint gateway.
        :param List[ReservedIPReference] ips: Collection of reserved IPs bound to
               an endpoint gateway.
        :param str lifecycle_state: The lifecycle state of the endpoint gateway.
        :param str name: The unique user-defined name for this endpoint gateway.
        :param ResourceGroupReference resource_group: The resource group for this
               endpoint gateway.
        :param str resource_type: The type of resource referenced.
        :param List[str] service_endpoints: Collection of fully qualified domain
               names for the target service.
        :param EndpointGatewayTarget target: The target for this endpoint gateway.
        :param VPCReference vpc: The VPC this endpoint gateway is serving.
        :param str service_endpoint: (optional) The fully qualified domain name for
               the target service.
        """
        self.created_at = created_at
        self.crn = crn
        self.health_state = health_state
        self.href = href
        self.id = id
        self.ips = ips
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.service_endpoint = service_endpoint
        self.service_endpoints = service_endpoints
        self.target = target
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGateway':
        """Initialize a EndpointGateway object from a json dictionary."""
        args = {}
        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 EndpointGateway JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in EndpointGateway JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError(
                'Required property \'health_state\' not present in EndpointGateway JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in EndpointGateway JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in EndpointGateway JSON')
        if 'ips' in _dict:
            args['ips'] = [
                ReservedIPReference.from_dict(x) for x in _dict.get('ips')
            ]
        else:
            raise ValueError(
                'Required property \'ips\' not present in EndpointGateway JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' not present in EndpointGateway JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in EndpointGateway 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 EndpointGateway JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in EndpointGateway JSON'
            )
        if 'service_endpoint' in _dict:
            args['service_endpoint'] = _dict.get('service_endpoint')
        if 'service_endpoints' in _dict:
            args['service_endpoints'] = _dict.get('service_endpoints')
        else:
            raise ValueError(
                'Required property \'service_endpoints\' not present in EndpointGateway JSON'
            )
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError(
                'Required property \'target\' not present in EndpointGateway JSON'
            )
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' not present in EndpointGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGateway object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ips') and self.ips is not None:
            _dict['ips'] = [x.to_dict() for x in self.ips]
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self,
                   'service_endpoint') and self.service_endpoint is not None:
            _dict['service_endpoint'] = self.service_endpoint
        if hasattr(self,
                   'service_endpoints') and self.service_endpoints is not None:
            _dict['service_endpoints'] = self.service_endpoints
        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 EndpointGateway object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGateway') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGateway') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: Healthy
        - `degraded`: Suffering from compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """
        OK = 'ok'
        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the endpoint gateway.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        ENDPOINT_GATEWAY = 'endpoint_gateway'


class EndpointGatewayCollection():
    """
    EndpointGatewayCollection.

    :attr List[EndpointGateway] endpoint_gateways: Collection of endpoint gateways.
    :attr EndpointGatewayCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr EndpointGatewayCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 endpoint_gateways: List['EndpointGateway'],
                 first: 'EndpointGatewayCollectionFirst',
                 limit: int,
                 total_count: int,
                 *,
                 next: 'EndpointGatewayCollectionNext' = None) -> None:
        """
        Initialize a EndpointGatewayCollection object.

        :param List[EndpointGateway] endpoint_gateways: Collection of endpoint
               gateways.
        :param EndpointGatewayCollectionFirst first: A link 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 EndpointGatewayCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.endpoint_gateways = endpoint_gateways
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayCollection':
        """Initialize a EndpointGatewayCollection object from a json dictionary."""
        args = {}
        if 'endpoint_gateways' in _dict:
            args['endpoint_gateways'] = [
                EndpointGateway.from_dict(x)
                for x in _dict.get('endpoint_gateways')
            ]
        else:
            raise ValueError(
                'Required property \'endpoint_gateways\' not present in EndpointGatewayCollection JSON'
            )
        if 'first' in _dict:
            args['first'] = EndpointGatewayCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in EndpointGatewayCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in EndpointGatewayCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = EndpointGatewayCollectionNext.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 EndpointGatewayCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'endpoint_gateways') and self.endpoint_gateways is not None:
            _dict['endpoint_gateways'] = [
                x.to_dict() for x in self.endpoint_gateways
            ]
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a EndpointGatewayCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayCollectionFirst':
        """Initialize a EndpointGatewayCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in EndpointGatewayCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayCollectionFirst object from 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 EndpointGatewayCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a EndpointGatewayCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayCollectionNext':
        """Initialize a EndpointGatewayCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in EndpointGatewayCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayCollectionNext object from 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 EndpointGatewayCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayPatch():
    """
    EndpointGatewayPatch.

    :attr str name: (optional) The user-defined name for this endpoint gateway.
          Names must be unique within the VPC this endpoint gateway is serving.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a EndpointGatewayPatch object.

        :param str name: (optional) The user-defined name for this endpoint
               gateway. Names must be unique within the VPC this endpoint gateway is
               serving.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayPatch':
        """Initialize a EndpointGatewayPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayPatch object from 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 EndpointGatewayPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a EndpointGatewayReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayReferenceDeleted':
        """Initialize a EndpointGatewayReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in EndpointGatewayReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIP():
    """
    A reserved IP to bind to the endpoint gateway. This can be an existing reserved IP, or
    a prototype used to allocate a reserved IP. The reserved IP will be bound to the
    endpoint gateway to function as a virtual private endpoint for the service.

    """

    def __init__(self) -> None:
        """
        Initialize a EndpointGatewayReservedIP object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'EndpointGatewayReservedIPReservedIPIdentity',
                'EndpointGatewayReservedIPReservedIPPrototypeTargetContext'
            ]))
        raise Exception(msg)


class EndpointGatewayTarget():
    """
    The target for this endpoint gateway.

    """

    def __init__(self) -> None:
        """
        Initialize a EndpointGatewayTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'EndpointGatewayTargetProviderCloudServiceReference',
                'EndpointGatewayTargetProviderInfrastructureServiceReference'
            ]))
        raise Exception(msg)


class EndpointGatewayTargetPrototype():
    """
    The target for this endpoint gateway.

    :attr str resource_type: The type of target for this endpoint gateway.
    """

    def __init__(self, resource_type: str) -> None:
        """
        Initialize a EndpointGatewayTargetPrototype object.

        :param str resource_type: The type of target for this endpoint gateway.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'EndpointGatewayTargetPrototypeProviderCloudServiceIdentity',
                'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototype':
        """Initialize a EndpointGatewayTargetPrototype 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 'EndpointGatewayTargetPrototype'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'EndpointGatewayTargetPrototypeProviderCloudServiceIdentity',
            'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity'
        ]))
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a EndpointGatewayTargetPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping[
            'provider_cloud_service'] = 'EndpointGatewayTargetPrototypeProviderCloudServiceIdentity'
        mapping[
            'provider_infrastructure_service'] = 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity'
        disc_value = _dict.get('resource_type')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'resource_type\' not found in EndpointGatewayTargetPrototype 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 ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'


class FloatingIP():
    """
    FloatingIP.

    :attr str address: The globally unique IP address.
    :attr datetime created_at: The date and time that the floating IP was created.
    :attr str crn: The CRN for this floating IP.
    :attr str href: The URL for this floating IP.
    :attr str id: The unique identifier for this floating IP.
    :attr str name: The unique user-defined name for this floating IP.
    :attr ResourceGroupReference resource_group: The resource group for this
          floating IP.
    :attr str status: The status of the floating IP.
    :attr FloatingIPTarget target: (optional) The target of this floating IP.
    :attr ZoneReference zone: The zone this floating IP resides in.
    """

    def __init__(self,
                 address: str,
                 created_at: datetime,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 status: str,
                 zone: 'ZoneReference',
                 *,
                 target: 'FloatingIPTarget' = None) -> None:
        """
        Initialize a FloatingIP object.

        :param str address: The globally unique IP address.
        :param datetime created_at: The date and time that the floating IP was
               created.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str id: The unique identifier for this floating IP.
        :param str name: The unique user-defined name for this floating IP.
        :param ResourceGroupReference resource_group: The resource group for this
               floating IP.
        :param str status: The status of the floating IP.
        :param ZoneReference zone: The zone this floating IP resides in.
        :param FloatingIPTarget target: (optional) The target of this floating IP.
        """
        self.address = address
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        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 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' 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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, '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, '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, '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 FloatingIPByTargetNetworkInterfaceIdentity():
    """
    The network interface this floating IP is to be bound to.

    """

    def __init__(self) -> None:
        """
        Initialize a FloatingIPByTargetNetworkInterfaceIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById',
                'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
            ]))
        raise Exception(msg)


class FloatingIPCollection():
    """
    FloatingIPCollection.

    :attr FloatingIPCollectionFirst first: A link to the first page of resources.
    :attr List[FloatingIP] floating_ips: Collection of floating IPs.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr FloatingIPCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'FloatingIPCollectionFirst',
                 floating_ips: List['FloatingIP'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'FloatingIPCollectionNext' = None) -> None:
        """
        Initialize a FloatingIPCollection object.

        :param FloatingIPCollectionFirst first: A link to the first page of
               resources.
        :param List[FloatingIP] floating_ips: Collection of floating IPs.
        :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 FloatingIPCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.floating_ips = floating_ips
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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, 'floating_ips') and self.floating_ips is not None:
            _dict['floating_ips'] = [x.to_dict() for x in self.floating_ips]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPCollectionNext object.

        :param str href: The URL for a 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 FloatingIPPatch():
    """
    FloatingIPPatch.

    :attr str name: (optional) The unique user-defined name for this floating IP.
    :attr 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.
    """

    def __init__(
            self,
            *,
            name: str = None,
            target: 'FloatingIPPatchTargetNetworkInterfaceIdentity' = None
    ) -> None:
        """
        Initialize a FloatingIPPatch object.

        :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.
        """
        self.name = name
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPPatch':
        """Initialize a FloatingIPPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPatch object from 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, '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 FloatingIPPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPPatch') -> 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 address: The globally unique IP address.
    :attr str crn: The CRN for this floating IP.
    :attr FloatingIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this floating IP.
    :attr str id: The unique identifier for this floating IP.
    :attr str name: The unique user-defined name for this floating IP.
    """

    def __init__(self,
                 address: str,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'FloatingIPReferenceDeleted' = None) -> None:
        """
        Initialize a FloatingIPReference object.

        :param str address: The globally unique IP address.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str id: The unique identifier for this floating IP.
        :param str name: The unique user-defined name for this floating IP.
        :param FloatingIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.address = address
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPReference':
        """Initialize a FloatingIPReference object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' 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 'deleted' in _dict:
            args['deleted'] = FloatingIPReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 FloatingIPReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a FloatingIPReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPReferenceDeleted':
        """Initialize a FloatingIPReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in FloatingIPReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPReferenceDeleted') -> 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 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 crn: The CRN for this flow log collector.
    :attr str href: The URL for this flow log collector.
    :attr str id: The unique identifier for this flow log collector.
    :attr str lifecycle_state: The lifecycle state of the 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 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, active: bool, auto_delete: bool, created_at: datetime,
                 crn: str, href: str, id: str, lifecycle_state: str, name: str,
                 resource_group: 'ResourceGroupReference',
                 storage_bucket: 'CloudObjectStorageBucketReference',
                 target: 'FlowLogCollectorTarget', vpc: 'VPCReference') -> None:
        """
        Initialize a FlowLogCollector object.

        :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 crn: The CRN for this flow log collector.
        :param str href: The URL for this flow log collector.
        :param str id: The unique identifier for this flow log collector.
        :param str lifecycle_state: The lifecycle state of the 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 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.active = active
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        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 '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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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 '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, '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, '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, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        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, '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 link to the first page of
          resources.
    :attr List[FlowLogCollector] flow_log_collectors: Collection of flow log
          collectors.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr FlowLogCollectorCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'FlowLogCollectorCollectionFirst',
                 flow_log_collectors: List['FlowLogCollector'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'FlowLogCollectorCollectionNext' = None) -> None:
        """
        Initialize a FlowLogCollectorCollection object.

        :param FlowLogCollectorCollectionFirst first: A link to the first page of
               resources.
        :param List[FlowLogCollector] flow_log_collectors: Collection of flow log
               collectors.
        :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 FlowLogCollectorCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.flow_log_collectors = flow_log_collectors
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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,
                '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
            ]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorCollectionNext object.

        :param str href: The URL for a 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 FlowLogCollectorPatch():
    """
    FlowLogCollectorPatch.

    :attr bool active: (optional) Indicates whether this collector is active.
          Updating to false deactivates the collector and updating to true activates the
          collector.
    :attr str name: (optional) The unique user-defined name for this flow log
          collector.
    """

    def __init__(self, *, active: bool = None, name: str = None) -> None:
        """
        Initialize a FlowLogCollectorPatch object.

        :param bool active: (optional) Indicates whether this collector is active.
               Updating to false deactivates the collector and updating to true activates
               the collector.
        :param str name: (optional) The unique user-defined name for this flow log
               collector.
        """
        self.active = active
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorPatch':
        """Initialize a FlowLogCollectorPatch object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPatch object from 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') and self.active is not None:
            _dict['active'] = self.active
        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 FlowLogCollectorPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 FlowLogCollectorTargetPrototype():
    """
    The target this collector will 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 FlowLogCollectorTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity',
                'FlowLogCollectorTargetPrototypeInstanceIdentity',
                'FlowLogCollectorTargetPrototypeSubnetIdentity',
                'FlowLogCollectorTargetPrototypeVPCIdentity'
            ]))
        raise Exception(msg)


class IKEPolicy():
    """
    IKEPolicy.

    :attr str authentication_algorithm: The authentication algorithm.
    :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 int dh_group: The Diffie-Hellman group.
    :attr str encryption_algorithm: The encryption algorithm.
    :attr str href: The IKE policy's canonical URL.
    :attr str id: The unique identifier for this IKE policy.
    :attr int ike_version: The IKE protocol version.
    :attr int key_lifetime: The key lifetime in seconds.
    :attr str name: The user-defined name for this IKE policy.
    :attr str negotiation_mode: The IKE negotiation mode. Only `main` is supported.
    :attr ResourceGroupReference resource_group: The resource group for this IKE
          policy.
    :attr str resource_type: The resource type.
    """

    def __init__(self, authentication_algorithm: str,
                 connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, dh_group: int, encryption_algorithm: str,
                 href: str, id: str, ike_version: int, key_lifetime: int,
                 name: str, negotiation_mode: str,
                 resource_group: 'ResourceGroupReference',
                 resource_type: str) -> None:
        """
        Initialize a IKEPolicy object.

        :param str authentication_algorithm: The authentication algorithm.
        :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 int dh_group: The Diffie-Hellman group.
        :param str encryption_algorithm: The encryption algorithm.
        :param str href: The IKE policy's canonical URL.
        :param str id: The unique identifier for this IKE policy.
        :param int ike_version: The IKE protocol version.
        :param int key_lifetime: The key lifetime in seconds.
        :param str name: The user-defined name for this IKE policy.
        :param str negotiation_mode: The IKE negotiation mode. Only `main` is
               supported.
        :param ResourceGroupReference resource_group: The resource group for this
               IKE policy.
        :param str resource_type: The resource type.
        """
        self.authentication_algorithm = authentication_algorithm
        self.connections = connections
        self.created_at = created_at
        self.dh_group = dh_group
        self.encryption_algorithm = encryption_algorithm
        self.href = href
        self.id = id
        self.ike_version = ike_version
        self.key_lifetime = key_lifetime
        self.name = name
        self.negotiation_mode = negotiation_mode
        self.resource_group = resource_group
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicy':
        """Initialize a IKEPolicy object from a json dictionary."""
        args = {}
        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 '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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicy JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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'
            )
        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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' 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, 'authentication_algorithm'
                  ) and self.authentication_algorithm is not None:
            _dict['authentication_algorithm'] = self.authentication_algorithm
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self,
                   'negotiation_mode') and self.negotiation_mode is not None:
            _dict['negotiation_mode'] = self.negotiation_mode
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        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 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 AuthenticationAlgorithmEnum(str, Enum):
        """
        The authentication algorithm.
        """
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA512 = 'sha512'

    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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        IKE_POLICY = 'ike_policy'


class IKEPolicyCollection():
    """
    IKEPolicyCollection.

    :attr IKEPolicyCollectionFirst first: A link to the first page of resources.
    :attr List[IKEPolicy] ike_policies: Collection of IKE policies.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr IKEPolicyCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'IKEPolicyCollectionFirst',
                 ike_policies: List['IKEPolicy'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'IKEPolicyCollectionNext' = None) -> None:
        """
        Initialize a IKEPolicyCollection object.

        :param IKEPolicyCollectionFirst first: A link to the first page of
               resources.
        :param List[IKEPolicy] ike_policies: Collection of IKE policies.
        :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 IKEPolicyCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.ike_policies = ike_policies
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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, 'ike_policies') and self.ike_policies is not None:
            _dict['ike_policies'] = [x.to_dict() for x in self.ike_policies]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IKEPolicyCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IKEPolicyCollectionNext object.

        :param str href: The URL for a 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 IKEPolicyPatch():
    """
    IKEPolicyPatch.

    :attr str authentication_algorithm: (optional) The authentication algorithm.
    :attr int dh_group: (optional) The Diffie-Hellman group.
    :attr str encryption_algorithm: (optional) The encryption algorithm.
    :attr int ike_version: (optional) The IKE protocol version.
    :attr int key_lifetime: (optional) The key lifetime in seconds.
    :attr str name: (optional) The user-defined name for this IKE policy.
    """

    def __init__(self,
                 *,
                 authentication_algorithm: str = None,
                 dh_group: int = None,
                 encryption_algorithm: str = None,
                 ike_version: int = None,
                 key_lifetime: int = None,
                 name: str = None) -> None:
        """
        Initialize a IKEPolicyPatch object.

        :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 str name: (optional) The user-defined name for this IKE policy.
        """
        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.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyPatch':
        """Initialize a IKEPolicyPatch object from a json dictionary."""
        args = {}
        if 'authentication_algorithm' in _dict:
            args['authentication_algorithm'] = _dict.get(
                'authentication_algorithm')
        if 'dh_group' in _dict:
            args['dh_group'] = _dict.get('dh_group')
        if 'encryption_algorithm' in _dict:
            args['encryption_algorithm'] = _dict.get('encryption_algorithm')
        if 'ike_version' in _dict:
            args['ike_version'] = _dict.get('ike_version')
        if 'key_lifetime' in _dict:
            args['key_lifetime'] = _dict.get('key_lifetime')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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, '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 IKEPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AuthenticationAlgorithmEnum(str, Enum):
        """
        The authentication algorithm.
        """
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA512 = 'sha512'

    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        """
        TRIPLE_DES = 'triple_des'
        AES128 = 'aes128'
        AES256 = 'aes256'


class IKEPolicyReference():
    """
    IKEPolicyReference.

    :attr IKEPolicyReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The IKE policy's canonical URL.
    :attr str id: The unique identifier for this IKE policy.
    :attr str name: The user-defined name for this IKE policy.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'IKEPolicyReferenceDeleted' = None) -> None:
        """
        Initialize a IKEPolicyReference object.

        :param str href: The IKE policy's canonical URL.
        :param str id: The unique identifier for this IKE policy.
        :param str name: The user-defined name for this IKE policy.
        :param str resource_type: The resource type.
        :param IKEPolicyReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        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 'deleted' in _dict:
            args['deleted'] = IKEPolicyReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IKEPolicyReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 IKEPolicyReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a IKEPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyReferenceDeleted':
        """Initialize a IKEPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in IKEPolicyReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 authentication_algorithm: The authentication algorithm.
    :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 encryption_algorithm: The encryption algorithm.
    :attr str href: The IPsec policy's canonical URL.
    :attr str id: The unique identifier for this IPsec policy.
    :attr int key_lifetime: The key lifetime in seconds.
    :attr str name: The user-defined name for this IPsec policy.
    :attr str pfs: Perfect Forward Secrecy.
    :attr ResourceGroupReference resource_group: The resource group for this IPsec
          policy.
    :attr str resource_type: The resource type.
    :attr str transform_protocol: The transform protocol used. Only `esp` is
          supported.
    """

    def __init__(self, authentication_algorithm: str,
                 connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, encapsulation_mode: str,
                 encryption_algorithm: str, href: str, id: str,
                 key_lifetime: int, name: str, pfs: str,
                 resource_group: 'ResourceGroupReference', resource_type: str,
                 transform_protocol: str) -> None:
        """
        Initialize a IPsecPolicy object.

        :param str authentication_algorithm: The authentication algorithm.
        :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 encryption_algorithm: The encryption algorithm.
        :param str href: The IPsec policy's canonical URL.
        :param str id: The unique identifier for this IPsec policy.
        :param int key_lifetime: The key lifetime in seconds.
        :param str name: The user-defined name for this IPsec policy.
        :param str pfs: Perfect Forward Secrecy.
        :param ResourceGroupReference resource_group: The resource group for this
               IPsec policy.
        :param str resource_type: The resource type.
        :param str transform_protocol: The transform protocol used. Only `esp` is
               supported.
        """
        self.authentication_algorithm = authentication_algorithm
        self.connections = connections
        self.created_at = created_at
        self.encapsulation_mode = encapsulation_mode
        self.encryption_algorithm = encryption_algorithm
        self.href = href
        self.id = id
        self.key_lifetime = key_lifetime
        self.name = name
        self.pfs = pfs
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.transform_protocol = transform_protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicy':
        """Initialize a IPsecPolicy object from a json dictionary."""
        args = {}
        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 '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 'encryption_algorithm' in _dict:
            args['encryption_algorithm'] = _dict.get('encryption_algorithm')
        else:
            raise ValueError(
                'Required property \'encryption_algorithm\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' 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, 'authentication_algorithm'
                  ) and self.authentication_algorithm is not None:
            _dict['authentication_algorithm'] = self.authentication_algorithm
        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, 'encryption_algorithm'
                  ) and self.encryption_algorithm is not None:
            _dict['encryption_algorithm'] = self.encryption_algorithm
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'key_lifetime') and self.key_lifetime is not None:
            _dict['key_lifetime'] = self.key_lifetime
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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 AuthenticationAlgorithmEnum(str, Enum):
        """
        The authentication algorithm.
        """
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA512 = 'sha512'

    class EncapsulationModeEnum(str, Enum):
        """
        The encapsulation mode used. Only `tunnel` is supported.
        """
        TUNNEL = 'tunnel'

    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_19 = 'group_19'
        GROUP_2 = 'group_2'
        GROUP_5 = 'group_5'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        IPSEC_POLICY = 'ipsec_policy'

    class TransformProtocolEnum(str, Enum):
        """
        The transform protocol used. Only `esp` is supported.
        """
        ESP = 'esp'


class IPsecPolicyCollection():
    """
    IPsecPolicyCollection.

    :attr IPsecPolicyCollectionFirst first: A link to the first page of resources.
    :attr List[IPsecPolicy] ipsec_policies: Collection of IPsec policies.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr IPsecPolicyCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'IPsecPolicyCollectionFirst',
                 ipsec_policies: List['IPsecPolicy'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'IPsecPolicyCollectionNext' = None) -> None:
        """
        Initialize a IPsecPolicyCollection object.

        :param IPsecPolicyCollectionFirst first: A link to the first page of
               resources.
        :param List[IPsecPolicy] ipsec_policies: Collection of IPsec policies.
        :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 IPsecPolicyCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.ipsec_policies = ipsec_policies
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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, 'ipsec_policies') and self.ipsec_policies is not None:
            _dict['ipsec_policies'] = [x.to_dict() for x in self.ipsec_policies]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IPsecPolicyCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a IPsecPolicyCollectionNext object.

        :param str href: The URL for a 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 IPsecPolicyPatch():
    """
    IPsecPolicyPatch.

    :attr str authentication_algorithm: (optional) The authentication algorithm.
    :attr str encryption_algorithm: (optional) The encryption algorithm.
    :attr int key_lifetime: (optional) The key lifetime in seconds.
    :attr str name: (optional) The user-defined name for this IPsec policy.
    :attr str pfs: (optional) Perfect Forward Secrecy.
    """

    def __init__(self,
                 *,
                 authentication_algorithm: str = None,
                 encryption_algorithm: str = None,
                 key_lifetime: int = None,
                 name: str = None,
                 pfs: str = None) -> None:
        """
        Initialize a IPsecPolicyPatch object.

        :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 name: (optional) The user-defined name for this IPsec policy.
        :param str pfs: (optional) Perfect Forward Secrecy.
        """
        self.authentication_algorithm = authentication_algorithm
        self.encryption_algorithm = encryption_algorithm
        self.key_lifetime = key_lifetime
        self.name = name
        self.pfs = pfs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyPatch':
        """Initialize a IPsecPolicyPatch object from a json dictionary."""
        args = {}
        if 'authentication_algorithm' in _dict:
            args['authentication_algorithm'] = _dict.get(
                'authentication_algorithm')
        if 'encryption_algorithm' in _dict:
            args['encryption_algorithm'] = _dict.get('encryption_algorithm')
        if 'key_lifetime' in _dict:
            args['key_lifetime'] = _dict.get('key_lifetime')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'pfs' in _dict:
            args['pfs'] = _dict.get('pfs')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'pfs') and self.pfs is not None:
            _dict['pfs'] = self.pfs
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AuthenticationAlgorithmEnum(str, Enum):
        """
        The authentication algorithm.
        """
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA512 = 'sha512'

    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_19 = 'group_19'
        GROUP_2 = 'group_2'
        GROUP_5 = 'group_5'


class IPsecPolicyReference():
    """
    IPsecPolicyReference.

    :attr IPsecPolicyReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The IPsec policy's canonical URL.
    :attr str id: The unique identifier for this IPsec policy.
    :attr str name: The user-defined name for this IPsec policy.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'IPsecPolicyReferenceDeleted' = None) -> None:
        """
        Initialize a IPsecPolicyReference object.

        :param str href: The IPsec policy's canonical URL.
        :param str id: The unique identifier for this IPsec policy.
        :param str name: The user-defined name for this IPsec policy.
        :param str resource_type: The resource type.
        :param IPsecPolicyReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        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 'deleted' in _dict:
            args['deleted'] = IPsecPolicyReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in IPsecPolicyReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 IPsecPolicyReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a IPsecPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyReferenceDeleted':
        """Initialize a IPsecPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in IPsecPolicyReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Image():
    """
    Image.

    :attr datetime created_at: The date and time that the image was created.
    :attr str crn: The CRN for this image.
    :attr str encryption: The type of encryption used on the image.
    :attr EncryptionKeyReference encryption_key: (optional) The key that will be
          used to encrypt volumes created from this image (unless an
          alternate `encryption_key` is provided at volume creation).
          This property will be present for images with an `encryption` type of
          `user_managed`.
    :attr ImageFile file: Details for the stored image file.
    :attr str href: The URL for this image.
    :attr str id: The unique identifier 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 str name: The user-defined or system-provided name for this image.
    :attr OperatingSystem operating_system: (optional) The operating system included
          in this image.
    :attr ResourceGroupReference resource_group: The resource group for this image.
    :attr str status: The status of this image
          - available: image can be used (provisionable)
          - deleting: image is being deleted, and can no longer be used to provision new
            resources
          - deprecated: image can be used, but is slated to become `obsolete`
          (provisionable)
          - failed: image is corrupt or did not pass validation
          - obsolete: image can no longer be used to provision new resources
          - pending: image is being imported and is not yet `available`
          - tentative: image import has timed out (contact support)
          - unusable: image cannot be used (see `status_reasons[]` for possible
          remediation)
          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 image on which the unexpected
          property value was encountered.
    :attr List[ImageStatusReason] status_reasons: Array of reasons for the current
          status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str visibility: Whether the image is publicly visible or private to the
          account.
    """

    def __init__(self,
                 created_at: datetime,
                 crn: str,
                 encryption: str,
                 file: 'ImageFile',
                 href: str,
                 id: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 status: str,
                 status_reasons: List['ImageStatusReason'],
                 visibility: str,
                 *,
                 encryption_key: 'EncryptionKeyReference' = None,
                 minimum_provisioned_size: int = None,
                 operating_system: 'OperatingSystem' = None) -> None:
        """
        Initialize a Image object.

        :param datetime created_at: The date and time that the image was created.
        :param str crn: The CRN for this image.
        :param str encryption: The type of encryption used on the image.
        :param ImageFile file: Details for the stored image file.
        :param str href: The URL for this image.
        :param str id: The unique identifier 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 str status: The status of this image
               - available: image can be used (provisionable)
               - deleting: image is being deleted, and can no longer be used to provision
               new
                 resources
               - deprecated: image can be used, but is slated to become `obsolete`
               (provisionable)
               - failed: image is corrupt or did not pass validation
               - obsolete: image can no longer be used to provision new resources
               - pending: image is being imported and is not yet `available`
               - tentative: image import has timed out (contact support)
               - unusable: image cannot be used (see `status_reasons[]` for possible
               remediation)
               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 image on
               which the unexpected property value was encountered.
        :param List[ImageStatusReason] status_reasons: Array of reasons for the
               current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str visibility: Whether the image is publicly visible or private to
               the account.
        :param EncryptionKeyReference encryption_key: (optional) The key that will
               be used to encrypt volumes created from this image (unless an
               alternate `encryption_key` is provided at volume creation).
               This property will be present for images with an `encryption` type of
               `user_managed`.
        :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.created_at = created_at
        self.crn = crn
        self.encryption = encryption
        self.encryption_key = encryption_key
        self.file = file
        self.href = href
        self.id = id
        self.minimum_provisioned_size = minimum_provisioned_size
        self.name = name
        self.operating_system = operating_system
        self.resource_group = resource_group
        self.status = status
        self.status_reasons = status_reasons
        self.visibility = visibility

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Image':
        """Initialize a Image object from a json dictionary."""
        args = {}
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Image JSON')
        if 'encryption' in _dict:
            args['encryption'] = _dict.get('encryption')
        else:
            raise ValueError(
                'Required property \'encryption\' not present in Image JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = EncryptionKeyReference.from_dict(
                _dict.get('encryption_key'))
        if 'file' in _dict:
            args['file'] = ImageFile.from_dict(_dict.get('file'))
        else:
            raise ValueError(
                'Required property \'file\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Image JSON')
        if 'minimum_provisioned_size' in _dict:
            args['minimum_provisioned_size'] = _dict.get(
                'minimum_provisioned_size')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in Image JSON')
        if 'operating_system' in _dict:
            args['operating_system'] = OperatingSystem.from_dict(
                _dict.get('operating_system'))
        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 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Image JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [
                ImageStatusReason.from_dict(x)
                for x in _dict.get('status_reasons')
            ]
        else:
            raise ValueError(
                'Required property \'status_reasons\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        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, 'file') and self.file is not None:
            _dict['file'] = self.file.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self,
                   'operating_system') and self.operating_system is not None:
            _dict['operating_system'] = self.operating_system.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, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            _dict['status_reasons'] = [x.to_dict() for x in self.status_reasons]
        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 EncryptionEnum(str, Enum):
        """
        The type of encryption used on the image.
        """
        NONE = 'none'
        USER_MANAGED = 'user_managed'

    class StatusEnum(str, Enum):
        """
        The status of this image
        - available: image can be used (provisionable)
        - deleting: image is being deleted, and can no longer be used to provision new
          resources
        - deprecated: image can be used, but is slated to become `obsolete`
        (provisionable)
        - failed: image is corrupt or did not pass validation
        - obsolete: image can no longer be used to provision new resources
        - pending: image is being imported and is not yet `available`
        - tentative: image import has timed out (contact support)
        - unusable: image cannot be used (see `status_reasons[]` for possible remediation)
        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 image on which the unexpected
        property value was encountered.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        DEPRECATED = 'deprecated'
        FAILED = 'failed'
        UNUSABLE = 'unusable'
        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 link to the first page of resources.
    :attr List[Image] images: Collection of images.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ImageCollectionNext next: (optional) A link to the next page of resources.
          This property is present for all pages
          except the last page.
    """

    def __init__(self,
                 first: 'ImageCollectionFirst',
                 images: List['Image'],
                 limit: int,
                 *,
                 next: 'ImageCollectionNext' = None) -> None:
        """
        Initialize a ImageCollection object.

        :param ImageCollectionFirst first: A link to the first page of resources.
        :param List[Image] images: Collection of images.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param ImageCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.images = images
        self.limit = limit
        self.next = next

    @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 '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'
            )
        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'))
        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, 'images') and self.images is not None:
            _dict['images'] = [x.to_dict() for x in self.images]
        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()
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ImageCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ImageCollectionNext object.

        :param str href: The URL for a 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 ImageFileChecksums checksums: (optional) Checksums for this image file.
          This property may be absent if the associated image has a `status` of `pending`
          or
          `failed`.
    :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,
                 *,
                 checksums: 'ImageFileChecksums' = None,
                 size: int = None) -> None:
        """
        Initialize a ImageFile object.

        :param ImageFileChecksums checksums: (optional) Checksums for this image
               file.
               This property may be absent if the associated image has a `status` of
               `pending` or
               `failed`.
        :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.checksums = checksums
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFile':
        """Initialize a ImageFile object from a json dictionary."""
        args = {}
        if 'checksums' in _dict:
            args['checksums'] = ImageFileChecksums.from_dict(
                _dict.get('checksums'))
        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, 'checksums') and self.checksums is not None:
            _dict['checksums'] = self.checksums.to_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 ImageFileChecksums():
    """
    ImageFileChecksums.

    :attr str sha256: (optional) The SHA256 fingerprint of the image file.
    """

    def __init__(self, *, sha256: str = None) -> None:
        """
        Initialize a ImageFileChecksums object.

        :param str sha256: (optional) The SHA256 fingerprint of the image file.
        """
        self.sha256 = sha256

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFileChecksums':
        """Initialize a ImageFileChecksums object from a json dictionary."""
        args = {}
        if 'sha256' in _dict:
            args['sha256'] = _dict.get('sha256')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageFileChecksums object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'sha256') and self.sha256 is not None:
            _dict['sha256'] = self.sha256
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageFileChecksums object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageFileChecksums') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageFileChecksums') -> 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 ImagePatch():
    """
    ImagePatch.

    :attr str name: (optional) The unique user-defined name for this image. Names
          starting with "ibm-" are not allowed.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a ImagePatch object.

        :param str name: (optional) The unique user-defined name for this image.
               Names starting with "ibm-" are not allowed.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImagePatch':
        """Initialize a ImagePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImagePatch object from 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 ImagePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImagePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImagePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 crn: The CRN for this image.
    :attr ImageReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this image.
    :attr str id: The unique identifier for this image.
    :attr str name: The user-defined or system-provided name for this image.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'ImageReferenceDeleted' = None) -> None:
        """
        Initialize a ImageReference object.

        :param str crn: The CRN for this image.
        :param str href: The URL for this image.
        :param str id: The unique identifier for this image.
        :param str name: The user-defined or system-provided name for this image.
        :param ImageReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageReference':
        """Initialize a ImageReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in ImageReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = ImageReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ImageReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 ImageReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a ImageReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageReferenceDeleted':
        """Initialize a ImageReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in ImageReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageStatusReason():
    """
    ImageStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(self,
                 code: str,
                 message: str,
                 *,
                 more_info: str = None) -> None:
        """
        Initialize a ImageStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageStatusReason':
        """Initialize a ImageStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError(
                'Required property \'code\' not present in ImageStatusReason JSON'
            )
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError(
                'Required property \'message\' not present in ImageStatusReason JSON'
            )
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """
        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'
        ENCRYPTION_KEY_DISABLED = 'encryption_key_disabled'


class Instance():
    """
    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 str crn: The CRN for this virtual server instance.
    :attr List[InstanceDisk] disks: Collection of the instance's disks.
    :attr InstanceGPU gpu: (optional) The virtual server instance GPU configuration.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr ImageReference image: (optional) The image the virtual server instance was
          provisioned from.
    :attr int memory: The amount of memory, truncated to whole gibibytes.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    :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 for this virtual server
          instance.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance.
    :attr str status: The status of the virtual server instance.
    :attr List[InstanceStatusReason] status_reasons: Array of reasons for the
          current status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :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 this virtual server instance resides in.
    :attr ZoneReference zone: The zone this virtual server instance resides in.
    """

    def __init__(
            self,
            bandwidth: int,
            boot_volume_attachment: 'VolumeAttachmentReferenceInstanceContext',
            created_at: datetime,
            crn: str,
            disks: List['InstanceDisk'],
            href: str,
            id: str,
            memory: int,
            name: str,
            network_interfaces: List[
                'NetworkInterfaceInstanceContextReference'],
            primary_network_interface:
        'NetworkInterfaceInstanceContextReference',
            profile: 'InstanceProfileReference',
            resource_group: 'ResourceGroupReference',
            status: str,
            status_reasons: List['InstanceStatusReason'],
            vcpu: 'InstanceVCPU',
            volume_attachments: List[
                'VolumeAttachmentReferenceInstanceContext'],
            vpc: 'VPCReference',
            zone: 'ZoneReference',
            *,
            gpu: 'InstanceGPU' = None,
            image: 'ImageReference' = None) -> None:
        """
        Initialize a Instance object.

        :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 str crn: The CRN for this virtual server instance.
        :param List[InstanceDisk] disks: Collection of the instance's disks.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param int memory: The amount of memory, truncated to whole gibibytes.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        :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 for this virtual
               server instance.
        :param ResourceGroupReference resource_group: The resource group for this
               instance.
        :param str status: The status of the virtual server instance.
        :param List[InstanceStatusReason] status_reasons: Array of reasons for the
               current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :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 this virtual server instance resides in.
        :param ZoneReference zone: The zone this 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.bandwidth = bandwidth
        self.boot_volume_attachment = boot_volume_attachment
        self.created_at = created_at
        self.crn = crn
        self.disks = disks
        self.gpu = gpu
        self.href = href
        self.id = id
        self.image = image
        self.memory = memory
        self.name = name
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.profile = profile
        self.resource_group = resource_group
        self.status = status
        self.status_reasons = status_reasons
        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 '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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in Instance JSON')
        if 'disks' in _dict:
            args['disks'] = [
                InstanceDisk.from_dict(x) for x in _dict.get('disks')
            ]
        else:
            raise ValueError(
                'Required property \'disks\' not present in Instance JSON')
        if 'gpu' in _dict:
            args['gpu'] = InstanceGPU.from_dict(_dict.get('gpu'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Instance JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in Instance JSON')
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 '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 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Instance JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [
                InstanceStatusReason.from_dict(x)
                for x in _dict.get('status_reasons')
            ]
        else:
            raise ValueError(
                'Required property \'status_reasons\' 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, '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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'disks') and self.disks is not None:
            _dict['disks'] = [x.to_dict() for x in self.disks]
        if hasattr(self, 'gpu') and self.gpu is not None:
            _dict['gpu'] = self.gpu.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, '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, 'status_reasons') and self.status_reasons is not None:
            _dict['status_reasons'] = [x.to_dict() for x in self.status_reasons]
        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.
        """
        DELETING = 'deleting'
        FAILED = 'failed'
        PAUSED = 'paused'
        PAUSING = 'pausing'
        PENDING = 'pending'
        RESTARTING = 'restarting'
        RESUMING = 'resuming'
        RUNNING = 'running'
        STARTING = 'starting'
        STOPPED = 'stopped'
        STOPPING = 'stopping'


class InstanceAction():
    """
    InstanceAction.

    :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 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 href: The URL for this instance action.
    :attr str id: The identifier for this instance action.
    :attr datetime started_at: (optional) The date and time that the action was
          started.
    :attr str status: The current status of this action.
    :attr str type: The type of action.
    """

    def __init__(self,
                 created_at: datetime,
                 href: str,
                 id: str,
                 status: str,
                 type: str,
                 *,
                 completed_at: datetime = None,
                 force: bool = None,
                 started_at: datetime = None) -> None:
        """
        Initialize a InstanceAction object.

        :param datetime created_at: The date and time that the action was created.
        :param str href: The URL for this instance action.
        :param str id: The identifier for this instance action.
        :param str status: The current status of this action.
        :param str type: The type of action.
        :param datetime completed_at: (optional) The date and time that the action
               was completed.
        :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 started_at: (optional) The date and time that the action
               was started.
        """
        self.completed_at = completed_at
        self.created_at = created_at
        self.force = force
        self.href = href
        self.id = id
        self.started_at = started_at
        self.status = status
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceAction':
        """Initialize a InstanceAction object from a json dictionary."""
        args = {}
        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 'force' in _dict:
            args['force'] = _dict.get('force')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceAction JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, '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, 'force') and self.force is not None:
            _dict['force'] = self.force
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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
        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 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 StatusEnum(str, Enum):
        """
        The current status of this action.
        """
        COMPLETED = 'completed'
        FAILED = 'failed'
        PENDING = 'pending'
        RUNNING = 'running'

    class TypeEnum(str, Enum):
        """
        The type of action.
        """
        REBOOT = 'reboot'
        START = 'start'
        STOP = 'stop'


class InstanceCollection():
    """
    InstanceCollection.

    :attr InstanceCollectionFirst first: A link to the first page of resources.
    :attr List[Instance] instances: Collection of virtual server instances.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'InstanceCollectionFirst',
                 instances: List['Instance'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'InstanceCollectionNext' = None) -> None:
        """
        Initialize a InstanceCollection object.

        :param InstanceCollectionFirst first: A link to the first page of
               resources.
        :param List[Instance] instances: Collection of virtual server instances.
        :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 InstanceCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.instances = instances
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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, 'instances') and self.instances is not None:
            _dict['instances'] = [x.to_dict() for x in self.instances]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceCollectionNext object.

        :param str href: The URL for a 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 InstanceConsoleAccessToken():
    """
    The instance console access token information.

    :attr str access_token: A URL safe single-use token used to access the console
          WebSocket.
    :attr str console_type: The instance console type for which this token may be
          used.
    :attr datetime created_at: The date and time that the access token was created.
    :attr datetime expires_at: The date and time that the access token will expire.
    :attr bool force: Indicates whether to disconnect an existing serial console
          session as the serial console cannot be shared.  This has no effect on VNC
          consoles.
    :attr str href: The URL to access this instance console.
    """

    def __init__(self, access_token: str, console_type: str,
                 created_at: datetime, expires_at: datetime, force: bool,
                 href: str) -> None:
        """
        Initialize a InstanceConsoleAccessToken object.

        :param str access_token: A URL safe single-use token used to access the
               console WebSocket.
        :param str console_type: The instance console type for which this token may
               be used.
        :param datetime created_at: The date and time that the access token was
               created.
        :param datetime expires_at: The date and time that the access token will
               expire.
        :param bool force: Indicates whether to disconnect an existing serial
               console session as the serial console cannot be shared.  This has no effect
               on VNC consoles.
        :param str href: The URL to access this instance console.
        """
        self.access_token = access_token
        self.console_type = console_type
        self.created_at = created_at
        self.expires_at = expires_at
        self.force = force
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceConsoleAccessToken':
        """Initialize a InstanceConsoleAccessToken object from a json dictionary."""
        args = {}
        if 'access_token' in _dict:
            args['access_token'] = _dict.get('access_token')
        else:
            raise ValueError(
                'Required property \'access_token\' not present in InstanceConsoleAccessToken JSON'
            )
        if 'console_type' in _dict:
            args['console_type'] = _dict.get('console_type')
        else:
            raise ValueError(
                'Required property \'console_type\' not present in InstanceConsoleAccessToken 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 InstanceConsoleAccessToken JSON'
            )
        if 'expires_at' in _dict:
            args['expires_at'] = string_to_datetime(_dict.get('expires_at'))
        else:
            raise ValueError(
                'Required property \'expires_at\' not present in InstanceConsoleAccessToken JSON'
            )
        if 'force' in _dict:
            args['force'] = _dict.get('force')
        else:
            raise ValueError(
                'Required property \'force\' not present in InstanceConsoleAccessToken JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceConsoleAccessToken JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceConsoleAccessToken object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'access_token') and self.access_token is not None:
            _dict['access_token'] = self.access_token
        if hasattr(self, 'console_type') and self.console_type is not None:
            _dict['console_type'] = self.console_type
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'expires_at') and self.expires_at is not None:
            _dict['expires_at'] = datetime_to_string(self.expires_at)
        if hasattr(self, 'force') and self.force is not None:
            _dict['force'] = self.force
        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 InstanceConsoleAccessToken object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceConsoleAccessToken') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceConsoleAccessToken') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConsoleTypeEnum(str, Enum):
        """
        The instance console type for which this token may be used.
        """
        VNC = 'vnc'
        SERIAL = 'serial'


class InstanceDisk():
    """
    InstanceDisk.

    :attr datetime created_at: The date and time that the disk was created.
    :attr str href: The URL for this instance disk.
    :attr str id: The unique identifier for this instance disk.
    :attr str interface_type: The disk interface used for attaching the disk.
          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 resource on which the unexpected
          property value was encountered.
    :attr str name: The user-defined name for this disk.
    :attr str resource_type: The resource type.
    :attr int size: The size of the disk in GB (gigabytes).
    """

    def __init__(self, created_at: datetime, href: str, id: str,
                 interface_type: str, name: str, resource_type: str,
                 size: int) -> None:
        """
        Initialize a InstanceDisk object.

        :param datetime created_at: The date and time that the disk was created.
        :param str href: The URL for this instance disk.
        :param str id: The unique identifier for this instance disk.
        :param str interface_type: The disk interface used for attaching the disk.
               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 resource on
               which the unexpected property value was encountered.
        :param str name: The user-defined name for this disk.
        :param str resource_type: The resource type.
        :param int size: The size of the disk in GB (gigabytes).
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.interface_type = interface_type
        self.name = name
        self.resource_type = resource_type
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDisk':
        """Initialize a InstanceDisk object from a json dictionary."""
        args = {}
        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 InstanceDisk JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceDisk JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceDisk JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError(
                'Required property \'interface_type\' not present in InstanceDisk JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceDisk JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in InstanceDisk JSON'
            )
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError(
                'Required property \'size\' not present in InstanceDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        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, '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 InstanceDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        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 resource on which the unexpected
        property value was encountered.
        """
        VIRTIO_BLK = 'virtio_blk'
        NVME = 'nvme'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_DISK = 'instance_disk'


class InstanceDiskCollection():
    """
    InstanceDiskCollection.

    :attr List[InstanceDisk] disks: Collection of the instance's disks.
    """

    def __init__(self, disks: List['InstanceDisk']) -> None:
        """
        Initialize a InstanceDiskCollection object.

        :param List[InstanceDisk] disks: Collection of the instance's disks.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskCollection':
        """Initialize a InstanceDiskCollection object from a json dictionary."""
        args = {}
        if 'disks' in _dict:
            args['disks'] = [
                InstanceDisk.from_dict(x) for x in _dict.get('disks')
            ]
        else:
            raise ValueError(
                'Required property \'disks\' not present in InstanceDiskCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'disks') and self.disks is not None:
            _dict['disks'] = [x.to_dict() for x in self.disks]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceDiskCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceDiskPatch():
    """
    InstanceDiskPatch.

    :attr str name: (optional) The user-defined name for this disk.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceDiskPatch object.

        :param str name: (optional) The user-defined name for this disk.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskPatch':
        """Initialize a InstanceDiskPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskPatch object from 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 InstanceDiskPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceDiskReference():
    """
    InstanceDiskReference.

    :attr InstanceDiskReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance disk.
    :attr str id: The unique identifier for this instance disk.
    :attr str name: The user-defined name for this disk.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'InstanceDiskReferenceDeleted' = None) -> None:
        """
        Initialize a InstanceDiskReference object.

        :param str href: The URL for this instance disk.
        :param str id: The unique identifier for this instance disk.
        :param str name: The user-defined name for this disk.
        :param str resource_type: The resource type.
        :param InstanceDiskReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskReference':
        """Initialize a InstanceDiskReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceDiskReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceDiskReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceDiskReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceDiskReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in InstanceDiskReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 InstanceDiskReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_DISK = 'instance_disk'


class InstanceDiskReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceDiskReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskReferenceDeleted':
        """Initialize a InstanceDiskReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceDiskReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceDiskReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskReferenceDeleted') -> 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 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 datetime created_at: The date and time that the instance group was
          created.
    :attr str crn: The CRN for this instance group.
    :attr str href: The URL for this instance group.
    :attr str id: The unique identifier for this instance group.
    :attr InstanceTemplateReference instance_template: The template used to create
          new instances for this group.
    :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 List[InstanceGroupManagerReference] managers: Array of references to
          managers for the instance group.
    :attr int membership_count: The number of instances in the instance group.
    :attr str name: The user-defined name for this 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 datetime updated_at: The date and time that the instance group was
          updated.
    :attr VPCReference vpc: The VPC the instance group resides in.
    """

    def __init__(
            self,
            created_at: datetime,
            crn: str,
            href: str,
            id: str,
            instance_template: 'InstanceTemplateReference',
            managers: List['InstanceGroupManagerReference'],
            membership_count: int,
            name: str,
            resource_group: 'ResourceGroupReference',
            status: str,
            subnets: List['SubnetReference'],
            updated_at: datetime,
            vpc: 'VPCReference',
            *,
            application_port: int = None,
            load_balancer_pool: 'LoadBalancerPoolReference' = None) -> None:
        """
        Initialize a InstanceGroup object.

        :param datetime created_at: The date and time that the instance group was
               created.
        :param str crn: The CRN for this instance group.
        :param str href: The URL for this instance group.
        :param str id: The unique identifier for this instance group.
        :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 int membership_count: The number of instances in the instance group.
        :param str name: The user-defined name for this 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 datetime updated_at: The date and time that the instance group was
               updated.
        :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.application_port = application_port
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.instance_template = instance_template
        self.load_balancer_pool = load_balancer_pool
        self.managers = managers
        self.membership_count = membership_count
        self.name = name
        self.resource_group = resource_group
        self.status = status
        self.subnets = subnets
        self.updated_at = updated_at
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroup':
        """Initialize a InstanceGroup object from a json dictionary."""
        args = {}
        if 'application_port' in _dict:
            args['application_port'] = _dict.get('application_port')
        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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'load_balancer_pool' in _dict:
            args['load_balancer_pool'] = LoadBalancerPoolReference.from_dict(
                _dict.get('load_balancer_pool'))
        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 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError(
                'Required property \'membership_count\' 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 '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 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' 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,
                   'application_port') and self.application_port is not None:
            _dict['application_port'] = self.application_port
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self,
                   'instance_template') and self.instance_template is not None:
            _dict['instance_template'] = self.instance_template.to_dict()
        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, 'managers') and self.managers is not None:
            _dict['managers'] = [x.to_dict() for x in self.managers]
        if hasattr(self,
                   'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        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, '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, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_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 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 link to the first page of resources.
    :attr List[InstanceGroup] instance_groups: Collection of instance groups.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'InstanceGroupCollectionFirst',
                 instance_groups: List['InstanceGroup'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'InstanceGroupCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupCollection object.

        :param InstanceGroupCollectionFirst first: A link to the first page of
               resources.
        :param List[InstanceGroup] instance_groups: Collection of instance groups.
        :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 InstanceGroupCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.instance_groups = instance_groups
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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,
                   'instance_groups') and self.instance_groups is not None:
            _dict['instance_groups'] = [
                x.to_dict() for x in self.instance_groups
            ]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupCollectionNext object.

        :param str href: The URL for a 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 datetime created_at: The date and time that the instance group manager was
          created.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr bool management_enabled: If set to `true`, this manager will control the
          instance group.
    :attr str name: The user-defined name for this instance group manager. Names
          must be unique within the instance group.
    :attr datetime updated_at: The date and time that the instance group manager was
          updated.
    """

    def __init__(self, created_at: datetime, href: str, id: str,
                 management_enabled: bool, name: str,
                 updated_at: datetime) -> None:
        """
        Initialize a InstanceGroupManager object.

        :param datetime created_at: The date and time that the instance group
               manager was created.
        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param bool management_enabled: If set to `true`, this manager will control
               the instance group.
        :param str name: The user-defined name for this instance group manager.
               Names must be unique within the instance group.
        :param datetime updated_at: The date and time that the instance group
               manager was updated.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerAutoScale', 'InstanceGroupManagerScheduled'
            ]))
        raise Exception(msg)


class InstanceGroupManagerAction():
    """
    InstanceGroupManagerAction.

    :attr bool auto_delete: If set to `true`, this scheduled action will be
          automatically deleted after it has finished and the `auto_delete_timeout` time
          has passed.
    :attr int auto_delete_timeout: Amount of time in hours that are required to pass
          before the scheduled action will be automatically deleted once it has finished.
          If this value is 0, the action will be deleted on completion.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The user-defined name for this instance group manager action.
          Names must be unique within the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was modified.
    """

    def __init__(self, auto_delete: bool, auto_delete_timeout: int,
                 created_at: datetime, href: str, id: str, name: str,
                 resource_type: str, status: str, updated_at: datetime) -> None:
        """
        Initialize a InstanceGroupManagerAction object.

        :param bool auto_delete: If set to `true`, this scheduled action will be
               automatically deleted after it has finished and the `auto_delete_timeout`
               time has passed.
        :param int auto_delete_timeout: Amount of time in hours that are required
               to pass before the scheduled action will be automatically deleted once it
               has finished. If this value is 0, the action will be deleted on completion.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The user-defined name for this instance group manager
               action. Names must be unique within the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was modified.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionScheduledAction']))
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'

    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """
        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'


class InstanceGroupManagerActionPatch():
    """
    InstanceGroupManagerActionPatch.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPatch object.

        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionPatchScheduledActionPatch']))
        raise Exception(msg)


class InstanceGroupManagerActionPrototype():
    """
    InstanceGroupManagerActionPrototype.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototype object.

        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerActionPrototypeScheduledActionPrototype'
            ]))
        raise Exception(msg)


class InstanceGroupManagerActionReference():
    """
    InstanceGroupManagerActionReference.

    :attr InstanceGroupManagerActionReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The user-defined name for this instance group manager action.
          Names must be unique within the instance group manager.
    :attr str resource_type: The resource type.
    """

    def __init__(
            self,
            href: str,
            id: str,
            name: str,
            resource_type: str,
            *,
            deleted: 'InstanceGroupManagerActionReferenceDeleted' = None
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionReference object.

        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The user-defined name for this instance group manager
               action. Names must be unique within the instance group manager.
        :param str resource_type: The resource type.
        :param InstanceGroupManagerActionReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionReference':
        """Initialize a InstanceGroupManagerActionReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args[
                'deleted'] = InstanceGroupManagerActionReferenceDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerActionReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerActionReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerActionReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in InstanceGroupManagerActionReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 InstanceGroupManagerActionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'


class InstanceGroupManagerActionReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceGroupManagerActionReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceGroupManagerActionReferenceDeleted':
        """Initialize a InstanceGroupManagerActionReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceGroupManagerActionReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerActionReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerActionReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionsCollection():
    """
    InstanceGroupManagerActionsCollection.

    :attr List[InstanceGroupManagerAction] actions: Collection of instance group
          manager actions.
    :attr InstanceGroupManagerActionsCollectionFirst first: A link to the first page
          of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupManagerActionsCollectionNext next: (optional) A link to the
          next page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
            self,
            actions: List['InstanceGroupManagerAction'],
            first: 'InstanceGroupManagerActionsCollectionFirst',
            limit: int,
            total_count: int,
            *,
            next: 'InstanceGroupManagerActionsCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollection object.

        :param List[InstanceGroupManagerAction] actions: Collection of instance
               group manager actions.
        :param InstanceGroupManagerActionsCollectionFirst first: A link 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 InstanceGroupManagerActionsCollectionNext next: (optional) A link to
               the next page of resources. This property is present for all pages
               except the last page.
        """
        self.actions = actions
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionsCollection':
        """Initialize a InstanceGroupManagerActionsCollection object from a json dictionary."""
        args = {}
        if 'actions' in _dict:
            args['actions'] = _dict.get('actions')
        else:
            raise ValueError(
                'Required property \'actions\' not present in InstanceGroupManagerActionsCollection JSON'
            )
        if 'first' in _dict:
            args[
                'first'] = InstanceGroupManagerActionsCollectionFirst.from_dict(
                    _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceGroupManagerActionsCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceGroupManagerActionsCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceGroupManagerActionsCollectionNext.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 InstanceGroupManagerActionsCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionsCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'actions') and self.actions is not None:
            actions_list = []
            for x in self.actions:
                if isinstance(x, dict):
                    actions_list.append(x)
                else:
                    actions_list.append(x.to_dict())
            _dict['actions'] = actions_list
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionsCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionsCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionsCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionsCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceGroupManagerActionsCollectionFirst':
        """Initialize a InstanceGroupManagerActionsCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerActionsCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionsCollectionFirst object from 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 InstanceGroupManagerActionsCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerActionsCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerActionsCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionsCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceGroupManagerActionsCollectionNext':
        """Initialize a InstanceGroupManagerActionsCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerActionsCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionsCollectionNext object from 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 InstanceGroupManagerActionsCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerActionsCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerActionsCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerCollection():
    """
    InstanceGroupManagerCollection.

    :attr InstanceGroupManagerCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[InstanceGroupManager] managers: Collection of instance group
          managers.
    :attr InstanceGroupManagerCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'InstanceGroupManagerCollectionFirst',
                 limit: int,
                 managers: List['InstanceGroupManager'],
                 total_count: int,
                 *,
                 next: 'InstanceGroupManagerCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupManagerCollection object.

        :param InstanceGroupManagerCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceGroupManager] managers: Collection of instance group
               managers.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupManagerCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.managers = managers
        self.next = next
        self.total_count = total_count

    @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 'managers' in _dict:
            args['managers'] = _dict.get('managers')
        else:
            raise ValueError(
                'Required property \'managers\' 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'
            )
        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, 'managers') and self.managers is not None:
            managers_list = []
            for x in self.managers:
                if isinstance(x, dict):
                    managers_list.append(x)
                else:
                    managers_list.append(x.to_dict())
            _dict['managers'] = managers_list
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerCollectionNext object.

        :param str href: The URL for a 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 InstanceGroupManagerPatch():
    """
    InstanceGroupManagerPatch.

    :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 bool management_enabled: (optional) If set to `true`, this manager will
          control the instance group.
    :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 name: (optional) The user-defined name for this instance group
          manager. Names must be unique within the instance group.
    """

    def __init__(self,
                 *,
                 aggregation_window: int = None,
                 cooldown: int = None,
                 management_enabled: bool = None,
                 max_membership_count: int = None,
                 min_membership_count: int = None,
                 name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerPatch object.

        :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 bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        :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 str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within the instance group.
        """
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.management_enabled = management_enabled
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPatch':
        """Initialize a InstanceGroupManagerPatch object from a json dictionary."""
        args = {}
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        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, '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 InstanceGroupManagerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicy():
    """
    InstanceGroupManagerPolicy.

    :attr datetime created_at: The date and time that the instance group manager
          policy was created.
    :attr str href: The URL for this instance group manager policy.
    :attr str id: The unique identifier 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 datetime updated_at: The date and time that the instance group manager
          policy was updated.
    """

    def __init__(self, created_at: datetime, href: str, id: str, name: str,
                 updated_at: datetime) -> None:
        """
        Initialize a InstanceGroupManagerPolicy object.

        :param datetime created_at: The date and time that the instance group
               manager policy was created.
        :param str href: The URL for this instance group manager policy.
        :param str id: The unique identifier 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 datetime updated_at: The date and time that the instance group
               manager policy was updated.
        """
        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 link 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 link to the
          next page of resources. This property is present for all pages
          except the last page.
    :attr List[InstanceGroupManagerPolicy] policies: Collection of instance group
          manager policies.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
            self,
            first: 'InstanceGroupManagerPolicyCollectionFirst',
            limit: int,
            policies: List['InstanceGroupManagerPolicy'],
            total_count: int,
            *,
            next: 'InstanceGroupManagerPolicyCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollection object.

        :param InstanceGroupManagerPolicyCollectionFirst first: A link to the first
               page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceGroupManagerPolicy] policies: Collection of instance
               group manager policies.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupManagerPolicyCollectionNext next: (optional) A link to
               the next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.policies = policies
        self.total_count = total_count

    @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 'policies' in _dict:
            args['policies'] = _dict.get('policies')
        else:
            raise ValueError(
                'Required property \'policies\' not present in InstanceGroupManagerPolicyCollection JSON'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, '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
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollectionNext object.

        :param str href: The URL for a 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 InstanceGroupManagerPolicyPatch():
    """
    InstanceGroupManagerPolicyPatch.

    :attr str metric_type: (optional) The type of metric to be evaluated.
    :attr int metric_value: (optional) The metric value to be evaluated.
    :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,
                 *,
                 metric_type: str = None,
                 metric_value: int = None,
                 name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerPolicyPatch object.

        :param str metric_type: (optional) The type of metric to be evaluated.
        :param int metric_value: (optional) The metric value to be evaluated.
        :param str name: (optional) The user-defined name for this instance group
               manager policy. Names must be unique within the instance group manager.
        """
        self.metric_type = metric_type
        self.metric_value = metric_value
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyPatch':
        """Initialize a InstanceGroupManagerPolicyPatch object from a json dictionary."""
        args = {}
        if 'metric_type' in _dict:
            args['metric_type'] = _dict.get('metric_type')
        if 'metric_value' in _dict:
            args['metric_value'] = _dict.get('metric_value')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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, '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 InstanceGroupManagerPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyPatch') -> 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 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 InstanceGroupManagerPolicyReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager policy.
    :attr str id: The unique identifier 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,
            href: str,
            id: str,
            name: str,
            *,
            deleted: 'InstanceGroupManagerPolicyReferenceDeleted' = None
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyReference object.

        :param str href: The URL for this instance group manager policy.
        :param str id: The unique identifier 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 InstanceGroupManagerPolicyReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyReference':
        """Initialize a InstanceGroupManagerPolicyReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args[
                'deleted'] = InstanceGroupManagerPolicyReferenceDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerPolicyReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 InstanceGroupManagerPolicyReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceGroupManagerPolicyReferenceDeleted':
        """Initialize a InstanceGroupManagerPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceGroupManagerPolicyReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPrototype():
    """
    InstanceGroupManagerPrototype.

    :attr bool management_enabled: (optional) If set to `true`, this manager will
          control the instance group.
    :attr str name: (optional) The user-defined name for this instance group
          manager. Names must be unique within the instance group.
    """

    def __init__(self,
                 *,
                 management_enabled: bool = None,
                 name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerPrototype object.

        :param bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        :param str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within the instance group.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype',
                'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype'
            ]))
        raise Exception(msg)


class InstanceGroupManagerReference():
    """
    InstanceGroupManagerReference.

    :attr InstanceGroupManagerReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier 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,
            href: str,
            id: str,
            name: str,
            *,
            deleted: 'InstanceGroupManagerReferenceDeleted' = None) -> None:
        """
        Initialize a InstanceGroupManagerReference object.

        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier 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 InstanceGroupManagerReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerReference':
        """Initialize a InstanceGroupManagerReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupManagerReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 InstanceGroupManagerReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceGroupManagerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerReferenceDeleted':
        """Initialize a InstanceGroupManagerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceGroupManagerReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionByManagerManager():
    """
    InstanceGroupManagerScheduledActionByManagerManager.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionByManagerManager object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototype'
            ]))
        raise Exception(msg)


class InstanceGroupManagerScheduledActionByManagerPatchManager():
    """
    InstanceGroupManagerScheduledActionByManagerPatchManager.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionByManagerPatchManager object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch'
            ]))
        raise Exception(msg)


class InstanceGroupManagerScheduledActionGroupGroup():
    """
    InstanceGroupManagerScheduledActionGroupGroup.

    :attr int membership_count: The number of members the instance group should have
          at the scheduled time.
    """

    def __init__(self, membership_count: int) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionGroupGroup object.

        :param int membership_count: The number of members the instance group
               should have at the scheduled time.
        """
        self.membership_count = membership_count

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceGroupManagerScheduledActionGroupGroup':
        """Initialize a InstanceGroupManagerScheduledActionGroupGroup object from a json dictionary."""
        args = {}
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError(
                'Required property \'membership_count\' not present in InstanceGroupManagerScheduledActionGroupGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionGroupGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_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 InstanceGroupManagerScheduledActionGroupGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerScheduledActionGroupGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerScheduledActionGroupGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionGroupPatch():
    """
    InstanceGroupManagerScheduledActionGroupPatch.

    :attr int membership_count: (optional) The number of members the instance group
          should have at the scheduled time.
    """

    def __init__(self, *, membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionGroupPatch object.

        :param int membership_count: (optional) The number of members the instance
               group should have at the scheduled time.
        """
        self.membership_count = membership_count

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceGroupManagerScheduledActionGroupPatch':
        """Initialize a InstanceGroupManagerScheduledActionGroupPatch object from a json dictionary."""
        args = {}
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionGroupPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_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 InstanceGroupManagerScheduledActionGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerScheduledActionGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerScheduledActionGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionGroupPrototype():
    """
    InstanceGroupManagerScheduledActionGroupPrototype.

    :attr int membership_count: The number of members the instance group should have
          at the scheduled time.
    """

    def __init__(self, membership_count: int) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionGroupPrototype object.

        :param int membership_count: The number of members the instance group
               should have at the scheduled time.
        """
        self.membership_count = membership_count

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceGroupManagerScheduledActionGroupPrototype':
        """Initialize a InstanceGroupManagerScheduledActionGroupPrototype object from a json dictionary."""
        args = {}
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError(
                'Required property \'membership_count\' not present in InstanceGroupManagerScheduledActionGroupPrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionGroupPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_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 InstanceGroupManagerScheduledActionGroupPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'InstanceGroupManagerScheduledActionGroupPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'InstanceGroupManagerScheduledActionGroupPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionManagerManager():
    """
    InstanceGroupManagerScheduledActionManagerManager.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerManager object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(
                ['InstanceGroupManagerScheduledActionManagerManagerAutoScale']))
        raise Exception(msg)


class InstanceGroupMembership():
    """
    InstanceGroupMembership.

    :attr datetime created_at: The date and time that the instance group manager
          policy was created.
    :attr bool delete_instance_on_membership_delete: If set to true, when deleting
          the membership the instance will also be deleted.
    :attr str href: The URL for this instance group membership.
    :attr str id: The unique identifier for this instance group membership.
    :attr InstanceReference instance:
    :attr InstanceTemplateReference instance_template:
    :attr str name: The user-defined name for this instance group membership. Names
          must be unique within the instance group.
    :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.
    :attr datetime updated_at: The date and time that the instance group membership
          was updated.
    """

    def __init__(self,
                 created_at: datetime,
                 delete_instance_on_membership_delete: bool,
                 href: str,
                 id: str,
                 instance: 'InstanceReference',
                 instance_template: 'InstanceTemplateReference',
                 name: str,
                 status: str,
                 updated_at: datetime,
                 *,
                 pool_member: 'LoadBalancerPoolMemberReference' = None) -> None:
        """
        Initialize a InstanceGroupMembership object.

        :param datetime created_at: The date and time that the instance group
               manager policy was created.
        :param bool delete_instance_on_membership_delete: If set to true, when
               deleting the membership the instance will also be deleted.
        :param str href: The URL for this instance group membership.
        :param str id: The unique identifier for this instance group membership.
        :param InstanceReference instance:
        :param InstanceTemplateReference instance_template:
        :param str name: The user-defined name for this instance group membership.
               Names must be unique within the instance group.
        :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 datetime updated_at: The date and time that the instance group
               membership was updated.
        :param LoadBalancerPoolMemberReference pool_member: (optional)
        """
        self.created_at = created_at
        self.delete_instance_on_membership_delete = delete_instance_on_membership_delete
        self.href = href
        self.id = id
        self.instance = instance
        self.instance_template = instance_template
        self.name = name
        self.pool_member = pool_member
        self.status = status
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembership':
        """Initialize a InstanceGroupMembership object from a json dictionary."""
        args = {}
        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 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupMembership JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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'
            )
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        return _dict

    def _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 link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[InstanceGroupMembership] memberships: Collection of instance group
          memberships.
    :attr InstanceGroupMembershipCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'InstanceGroupMembershipCollectionFirst',
                 limit: int,
                 memberships: List['InstanceGroupMembership'],
                 total_count: int,
                 *,
                 next: 'InstanceGroupMembershipCollectionNext' = None) -> None:
        """
        Initialize a InstanceGroupMembershipCollection object.

        :param InstanceGroupMembershipCollectionFirst first: A link to the first
               page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceGroupMembership] memberships: Collection of instance
               group memberships.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupMembershipCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.memberships = memberships
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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, 'memberships') and self.memberships is not None:
            _dict['memberships'] = [x.to_dict() for x in self.memberships]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupMembershipCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceGroupMembershipCollectionNext object.

        :param str href: The URL for a 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 InstanceGroupMembershipPatch():
    """
    InstanceGroupMembershipPatch.

    :attr str name: (optional) The user-defined name for this instance group
          membership. Names must be unique within the instance group.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceGroupMembershipPatch object.

        :param str name: (optional) The user-defined name for this instance group
               membership. Names must be unique within the instance group.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipPatch':
        """Initialize a InstanceGroupMembershipPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipPatch object from 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 InstanceGroupMembershipPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupPatch():
    """
    To add or update load balancer specification for an instance group the
    `membership_count` must first be set to 0.

    :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 InstanceTemplateIdentity instance_template: (optional) Instance template
          to use when creating new instances.
    :attr 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.
    :attr 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`.
    :attr int membership_count: (optional) The number of instances in the instance
          group.
    :attr str name: (optional) The user-defined name for this instance group.
    :attr List[SubnetIdentity] subnets: (optional) Array of identities to subnets to
          use when creating new instances.
    """

    def __init__(self,
                 *,
                 application_port: int = None,
                 instance_template: 'InstanceTemplateIdentity' = None,
                 load_balancer: 'LoadBalancerIdentity' = None,
                 load_balancer_pool: 'LoadBalancerPoolIdentity' = None,
                 membership_count: int = None,
                 name: str = None,
                 subnets: List['SubnetIdentity'] = None) -> None:
        """
        Initialize a InstanceGroupPatch object.

        :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 InstanceTemplateIdentity instance_template: (optional) Instance
               template to use when creating new instances.
        :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 int membership_count: (optional) The number of instances in the
               instance group.
        :param str name: (optional) The user-defined name for this instance group.
        :param List[SubnetIdentity] subnets: (optional) Array of identities to
               subnets to use when creating new instances.
        """
        self.application_port = application_port
        self.instance_template = instance_template
        self.load_balancer = load_balancer
        self.load_balancer_pool = load_balancer_pool
        self.membership_count = membership_count
        self.name = name
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupPatch':
        """Initialize a InstanceGroupPatch object from a json dictionary."""
        args = {}
        if 'application_port' in _dict:
            args['application_port'] = _dict.get('application_port')
        if 'instance_template' in _dict:
            args['instance_template'] = _dict.get('instance_template')
        if 'load_balancer' in _dict:
            args['load_balancer'] = _dict.get('load_balancer')
        if 'load_balancer_pool' in _dict:
            args['load_balancer_pool'] = _dict.get('load_balancer_pool')
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'subnets' in _dict:
            args['subnets'] = _dict.get('subnets')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'application_port') and self.application_port is not None:
            _dict['application_port'] = self.application_port
        if hasattr(self,
                   'instance_template') and self.instance_template is not None:
            if isinstance(self.instance_template, dict):
                _dict['instance_template'] = self.instance_template
            else:
                _dict['instance_template'] = self.instance_template.to_dict()
        if hasattr(self, 'load_balancer') and self.load_balancer is not None:
            if isinstance(self.load_balancer, dict):
                _dict['load_balancer'] = self.load_balancer
            else:
                _dict['load_balancer'] = self.load_balancer.to_dict()
        if hasattr(
                self,
                'load_balancer_pool') and self.load_balancer_pool is not None:
            if isinstance(self.load_balancer_pool, dict):
                _dict['load_balancer_pool'] = self.load_balancer_pool
            else:
                _dict['load_balancer_pool'] = self.load_balancer_pool.to_dict()
        if hasattr(self,
                   'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for x in self.subnets:
                if isinstance(x, dict):
                    subnets_list.append(x)
                else:
                    subnets_list.append(x.to_dict())
            _dict['subnets'] = subnets_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 InstanceGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupReference():
    """
    InstanceGroupReference.

    :attr str crn: The CRN for this instance group.
    :attr InstanceGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance group.
    :attr str id: The unique identifier for this instance group.
    :attr str name: The user-defined name for this instance group.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'InstanceGroupReferenceDeleted' = None) -> None:
        """
        Initialize a InstanceGroupReference object.

        :param str crn: The CRN for this instance group.
        :param str href: The URL for this instance group.
        :param str id: The unique identifier for this instance group.
        :param str name: The user-defined name for this instance group.
        :param InstanceGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupReference':
        """Initialize a InstanceGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceGroupReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 InstanceGroupReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupReferenceDeleted':
        """Initialize a InstanceGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceGroupReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupReferenceDeleted') -> 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 InstancePatch():
    """
    InstancePatch.

    :attr str name: (optional) The user-defined name for this virtual server
          instance (and default system hostname).
    :attr InstancePatchProfile profile: (optional) The profile to use for this
          virtual server instance. For the profile to be changed,
          the instance `status` must be `stopping` or `stopped`. In addition, the
          requested
          profile must:
          - Match the current profile's instance disk support. (Note: If the current
          profile
            supports instance storage disks, the requested profile can have a different
            instance storage disk configuration.)
          - Be compatible with any `placement_target` constraints. For example, if the
            instance is placed on a dedicated host, the requested profile `family` must be
            the same as the dedicated host `family`.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 profile: 'InstancePatchProfile' = None) -> None:
        """
        Initialize a InstancePatch object.

        :param str name: (optional) The user-defined name for this virtual server
               instance (and default system hostname).
        :param InstancePatchProfile profile: (optional) The profile to use for this
               virtual server instance. For the profile to be changed,
               the instance `status` must be `stopping` or `stopped`. In addition, the
               requested
               profile must:
               - Match the current profile's instance disk support. (Note: If the current
               profile
                 supports instance storage disks, the requested profile can have a
               different
                 instance storage disk configuration.)
               - Be compatible with any `placement_target` constraints. For example, if
               the
                 instance is placed on a dedicated host, the requested profile `family`
               must be
                 the same as the dedicated host `family`.
        """
        self.name = name
        self.profile = profile

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePatch':
        """Initialize a InstancePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePatch object from 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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePatchProfile():
    """
    The profile to use for this virtual server instance. For the profile to be changed,
    the instance `status` must be `stopping` or `stopped`. In addition, the requested
    profile must:
    - Match the current profile's instance disk support. (Note: If the current profile
      supports instance storage disks, the requested profile can have a different
      instance storage disk configuration.)
    - Be compatible with any `placement_target` constraints. For example, if the
      instance is placed on a dedicated host, the requested profile `family` must be
      the same as the dedicated host `family`.

    """

    def __init__(self) -> None:
        """
        Initialize a InstancePatchProfile object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstancePatchProfileInstanceProfileIdentityByName',
                'InstancePatchProfileInstanceProfileIdentityByHref'
            ]))
        raise Exception(msg)


class InstancePlacementTargetPrototype():
    """
    InstancePlacementTargetPrototype.

    """

    def __init__(self) -> None:
        """
        Initialize a InstancePlacementTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstancePlacementTargetPrototypeDedicatedHostIdentity',
                'InstancePlacementTargetPrototypeDedicatedHostGroupIdentity'
            ]))
        raise Exception(msg)


class InstanceProfile():
    """
    InstanceProfile.

    :attr InstanceProfileBandwidth bandwidth:
    :attr List[InstanceProfileDisk] disks: Collection of the instance profile's
          disks.
    :attr str family: (optional) The product family this virtual server instance
          profile belongs to.
    :attr str href: The URL for this virtual server instance profile.
    :attr InstanceProfileMemory memory:
    :attr str name: The globally unique name for this virtual server instance
          profile.
    :attr InstanceProfileOSArchitecture os_architecture:
    :attr InstanceProfilePortSpeed port_speed:
    :attr InstanceProfileVCPUArchitecture vcpu_architecture:
    :attr InstanceProfileVCPU vcpu_count:
    """

    def __init__(self,
                 bandwidth: 'InstanceProfileBandwidth',
                 disks: List['InstanceProfileDisk'],
                 href: str,
                 memory: 'InstanceProfileMemory',
                 name: str,
                 os_architecture: 'InstanceProfileOSArchitecture',
                 port_speed: 'InstanceProfilePortSpeed',
                 vcpu_architecture: 'InstanceProfileVCPUArchitecture',
                 vcpu_count: 'InstanceProfileVCPU',
                 *,
                 family: str = None) -> None:
        """
        Initialize a InstanceProfile object.

        :param InstanceProfileBandwidth bandwidth:
        :param List[InstanceProfileDisk] disks: Collection of the instance
               profile's disks.
        :param str href: The URL for this virtual server instance profile.
        :param InstanceProfileMemory memory:
        :param str name: The globally unique name for this virtual server instance
               profile.
        :param InstanceProfileOSArchitecture os_architecture:
        :param InstanceProfilePortSpeed port_speed:
        :param InstanceProfileVCPUArchitecture vcpu_architecture:
        :param InstanceProfileVCPU vcpu_count:
        :param str family: (optional) The product family this virtual server
               instance profile belongs to.
        """
        self.bandwidth = bandwidth
        self.disks = disks
        self.family = family
        self.href = href
        self.memory = memory
        self.name = name
        self.os_architecture = os_architecture
        self.port_speed = port_speed
        self.vcpu_architecture = vcpu_architecture
        self.vcpu_count = vcpu_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfile':
        """Initialize a InstanceProfile object from a json dictionary."""
        args = {}
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError(
                'Required property \'bandwidth\' not present in InstanceProfile JSON'
            )
        if 'disks' in _dict:
            args['disks'] = [
                InstanceProfileDisk.from_dict(x) for x in _dict.get('disks')
            ]
        else:
            raise ValueError(
                'Required property \'disks\' not present in InstanceProfile JSON'
            )
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError(
                'Required property \'port_speed\' 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'
            )
        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, '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, 'disks') and self.disks is not None:
            _dict['disks'] = [x.to_dict() for x in self.disks]
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self,
                   'os_architecture') and self.os_architecture is not None:
            _dict['os_architecture'] = self.os_architecture.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,
                   '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()
        return _dict

    def _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 InstanceProfileDisk():
    """
    Disks provided by this profile.

    :attr InstanceProfileDiskQuantity quantity:
    :attr InstanceProfileDiskSize size:
    :attr InstanceProfileDiskSupportedInterfaces supported_interface_types:
    """

    def __init__(
        self, quantity: 'InstanceProfileDiskQuantity',
        size: 'InstanceProfileDiskSize',
        supported_interface_types: 'InstanceProfileDiskSupportedInterfaces'
    ) -> None:
        """
        Initialize a InstanceProfileDisk object.

        :param InstanceProfileDiskQuantity quantity:
        :param InstanceProfileDiskSize size:
        :param InstanceProfileDiskSupportedInterfaces supported_interface_types:
        """
        self.quantity = quantity
        self.size = size
        self.supported_interface_types = supported_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDisk':
        """Initialize a InstanceProfileDisk object from a json dictionary."""
        args = {}
        if 'quantity' in _dict:
            args['quantity'] = _dict.get('quantity')
        else:
            raise ValueError(
                'Required property \'quantity\' not present in InstanceProfileDisk JSON'
            )
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError(
                'Required property \'size\' not present in InstanceProfileDisk JSON'
            )
        if 'supported_interface_types' in _dict:
            args[
                'supported_interface_types'] = InstanceProfileDiskSupportedInterfaces.from_dict(
                    _dict.get('supported_interface_types'))
        else:
            raise ValueError(
                'Required property \'supported_interface_types\' not present in InstanceProfileDisk JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'quantity') and self.quantity is not None:
            if isinstance(self.quantity, dict):
                _dict['quantity'] = self.quantity
            else:
                _dict['quantity'] = self.quantity.to_dict()
        if hasattr(self, 'size') and self.size is not None:
            if isinstance(self.size, dict):
                _dict['size'] = self.size
            else:
                _dict['size'] = self.size.to_dict()
        if hasattr(self, 'supported_interface_types'
                  ) and self.supported_interface_types is not None:
            _dict[
                'supported_interface_types'] = self.supported_interface_types.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 InstanceProfileDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileDiskQuantity():
    """
    InstanceProfileDiskQuantity.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfileDiskQuantity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfileDiskQuantityFixed',
                'InstanceProfileDiskQuantityRange',
                'InstanceProfileDiskQuantityEnum',
                'InstanceProfileDiskQuantityDependent'
            ]))
        raise Exception(msg)


class InstanceProfileDiskSize():
    """
    InstanceProfileDiskSize.

    """

    def __init__(self) -> None:
        """
        Initialize a InstanceProfileDiskSize object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceProfileDiskSizeFixed', 'InstanceProfileDiskSizeRange',
                'InstanceProfileDiskSizeEnum',
                'InstanceProfileDiskSizeDependent'
            ]))
        raise Exception(msg)


class InstanceProfileDiskSupportedInterfaces():
    """
    InstanceProfileDiskSupportedInterfaces.

    :attr str default: The disk interface used for attaching the disk.
          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 resource on which the unexpected
          property value was encountered.
    :attr str type: The type for this profile field.
    :attr List[str] values: The supported disk interfaces used for attaching the
          disk.
    """

    def __init__(self, default: str, type: str, values: List[str]) -> None:
        """
        Initialize a InstanceProfileDiskSupportedInterfaces object.

        :param str default: The disk interface used for attaching the disk.
               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 resource on
               which the unexpected property value was encountered.
        :param str type: The type for this profile field.
        :param List[str] values: The supported disk interfaces used for attaching
               the disk.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSupportedInterfaces':
        """Initialize a InstanceProfileDiskSupportedInterfaces object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileDiskSupportedInterfaces JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskSupportedInterfaces JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileDiskSupportedInterfaces JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSupportedInterfaces object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 InstanceProfileDiskSupportedInterfaces object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DefaultEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        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 resource on which the unexpected
        property value was encountered.
        """
        VIRTIO_BLK = 'virtio_blk'
        NVME = 'nvme'

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        ENUM = 'enum'

    class ValuesEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        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 resource on which the unexpected
        property value was encountered.
        """
        VIRTIO_BLK = 'virtio_blk'
        NVME = 'nvme'


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 default: The default OS architecture for an instance with this
          profile.
    :attr str type: The type for this profile field.
    :attr List[str] values: The supported OS architecture(s) for an instance with
          this profile.
    """

    def __init__(self, default: str, type: str, values: List[str]) -> None:
        """
        Initialize a InstanceProfileOSArchitecture object.

        :param str default: The default OS architecture for an instance with this
               profile.
        :param str type: The type for this profile field.
        :param List[str] values: The supported OS architecture(s) for an instance
               with this profile.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileOSArchitecture':
        """Initialize a InstanceProfileOSArchitecture object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileOSArchitecture JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 href: The URL for this virtual server instance profile.
    :attr str name: The globally unique name for this virtual server instance
          profile.
    """

    def __init__(self, href: str, name: str) -> None:
        """
        Initialize a InstanceProfileReference object.

        :param str href: The URL for this virtual server instance profile.
        :param str name: The globally unique name for this virtual server instance
               profile.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileReference':
        """Initialize a InstanceProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceProfileReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, '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 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 default: (optional) The default VCPU architecture for an instance with
          this profile.
    :attr str type: The type for this profile field.
    :attr str value: The 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.default = default
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUArchitecture':
        """Initialize a InstanceProfileVCPUArchitecture object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        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'
            )
        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, 'default') and self.default is not None:
            _dict['default'] = self.default
        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 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 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 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[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :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 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.
    """

    def __init__(self,
                 *,
                 keys: List['KeyIdentity'] = None,
                 name: str = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 placement_target: 'InstancePlacementTargetPrototype' = None,
                 profile: 'InstanceProfileIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None) -> None:
        """
        Initialize a InstancePrototype object.

        :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 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[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :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 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([
                'InstancePrototypeInstanceByImage',
                'InstancePrototypeInstanceBySourceTemplate'
            ]))
        raise Exception(msg)


class InstanceReference():
    """
    InstanceReference.

    :attr str crn: The CRN for this virtual server instance.
    :attr InstanceReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'InstanceReferenceDeleted' = None) -> None:
        """
        Initialize a InstanceReference object.

        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        :param InstanceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReference':
        """Initialize a InstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = InstanceReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 InstanceReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReferenceDeleted':
        """Initialize a InstanceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceStatusReason():
    """
    InstanceStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(self,
                 code: str,
                 message: str,
                 *,
                 more_info: str = None) -> None:
        """
        Initialize a InstanceStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceStatusReason':
        """Initialize a InstanceStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError(
                'Required property \'code\' not present in InstanceStatusReason JSON'
            )
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError(
                'Required property \'message\' not present in InstanceStatusReason JSON'
            )
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """
        CANNOT_START = 'cannot_start'
        CANNOT_START_CAPACITY = 'cannot_start_capacity'
        CANNOT_START_COMPUTE = 'cannot_start_compute'
        CANNOT_START_IP_ADDRESS = 'cannot_start_ip_address'
        CANNOT_START_NETWORK = 'cannot_start_network'
        CANNOT_START_STORAGE = 'cannot_start_storage'
        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'


class InstanceTemplate():
    """
    InstanceTemplate.

    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier 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 str name: The unique user-defined name for this instance template.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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.
    """

    def __init__(self,
                 created_at: datetime,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 *,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 placement_target: 'InstancePlacementTargetPrototype' = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None) -> None:
        """
        Initialize a InstanceTemplate object.

        :param datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :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 InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use 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 link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[InstanceTemplate] templates: Collection of instance templates.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'InstanceTemplateCollectionFirst',
                 limit: int,
                 templates: List['InstanceTemplate'],
                 total_count: int,
                 *,
                 next: 'InstanceTemplateCollectionNext' = None) -> None:
        """
        Initialize a InstanceTemplateCollection object.

        :param InstanceTemplateCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceTemplate] templates: Collection of instance templates.
        :param int total_count: The total number of resources across all pages.
        :param InstanceTemplateCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.templates = templates
        self.total_count = total_count

    @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 'templates' in _dict:
            args['templates'] = _dict.get('templates')
        else:
            raise ValueError(
                'Required property \'templates\' not present in InstanceTemplateCollection JSON'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, '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
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceTemplateCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstanceTemplateCollectionNext object.

        :param str href: The URL for a 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 InstanceTemplatePatch():
    """
    InstanceTemplatePatch.

    :attr str name: (optional) The unique user-defined name for this instance
          template.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceTemplatePatch object.

        :param str name: (optional) The unique user-defined name for this instance
               template.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePatch':
        """Initialize a InstanceTemplatePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePatch object from 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 InstanceTemplatePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototype():
    """
    InstanceTemplatePrototype.

    :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 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[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :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 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.
    """

    def __init__(self,
                 *,
                 keys: List['KeyIdentity'] = None,
                 name: str = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 placement_target: 'InstancePlacementTargetPrototype' = None,
                 profile: 'InstanceProfileIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None) -> None:
        """
        Initialize a InstanceTemplatePrototype object.

        :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 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[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :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 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([
                'InstanceTemplatePrototypeInstanceByImage',
                'InstanceTemplatePrototypeInstanceBySourceTemplate'
            ]))
        raise Exception(msg)


class InstanceTemplateReference():
    """
    InstanceTemplateReference.

    :attr str crn: The CRN for this instance template.
    :attr InstanceTemplateReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier for this instance template.
    :attr str name: The unique user-defined name for this instance template.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'InstanceTemplateReferenceDeleted' = None) -> None:
        """
        Initialize a InstanceTemplateReference object.

        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :param InstanceTemplateReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateReference':
        """Initialize a InstanceTemplateReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceTemplateReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = InstanceTemplateReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceTemplateReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 InstanceTemplateReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a InstanceTemplateReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateReferenceDeleted':
        """Initialize a InstanceTemplateReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in InstanceTemplateReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateReferenceDeleted') -> 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 datetime created_at: The date and time that the key was created.
    :attr str crn: The CRN 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 href: The URL for this key.
    :attr str id: The unique identifier for this key.
    :attr int length: The length of this key (in bits).
    :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 ResourceGroupReference resource_group: The resource group for this key.
    :attr str type: The crypto-system used by this key.
    """

    def __init__(self, created_at: datetime, crn: str, fingerprint: str,
                 href: str, id: str, length: int, name: str, public_key: str,
                 resource_group: 'ResourceGroupReference', type: str) -> None:
        """
        Initialize a Key object.

        :param datetime created_at: The date and time that the key was created.
        :param str crn: The CRN 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 href: The URL for this key.
        :param str id: The unique identifier for this key.
        :param int length: The length of this key (in bits).
        :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 ResourceGroupReference resource_group: The resource group for this
               key.
        :param str type: The crypto-system used by this key.
        """
        self.created_at = created_at
        self.crn = crn
        self.fingerprint = fingerprint
        self.href = href
        self.id = id
        self.length = length
        self.name = name
        self.public_key = public_key
        self.resource_group = resource_group
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Key':
        """Initialize a Key object from a json dictionary."""
        args = {}
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Key JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' 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')
        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 '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 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'length') and self.length is not None:
            _dict['length'] = self.length
        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, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.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 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 crypto-system 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 KeyPatch():
    """
    KeyPatch.

    :attr str name: (optional) The user-defined name for this key.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a KeyPatch object.

        :param str name: (optional) The user-defined name for this key.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyPatch':
        """Initialize a KeyPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyPatch object from 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 KeyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a KeyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyReferenceDeleted':
        """Initialize a KeyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in KeyReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 datetime created_at: The date and time that this load balancer was
          created.
    :attr str crn: The load balancer's CRN.
    :attr str hostname: Fully qualified domain name assigned to this load balancer.
    :attr str href: The load balancer's canonical URL.
    :attr str id: The unique identifier for 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 LoadBalancerLogging logging: The logging configuration for this load
          balancer.
    :attr str name: The unique user-defined name for 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 LoadBalancerProfileReference profile: The profile to use for 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.
          Applicable only for public load balancers.
    :attr ResourceGroupReference resource_group: The resource group for this load
          balancer.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this load balancer.
          Applicable only for load balancers that support security groups.
    :attr bool security_groups_supported: Indicates whether this load balancer
          supports security groups.
    :attr List[SubnetReference] subnets: The subnets this load balancer is part of.
    """

    def __init__(self, created_at: datetime, crn: str, hostname: str, href: str,
                 id: str, is_public: bool,
                 listeners: List['LoadBalancerListenerReference'],
                 logging: 'LoadBalancerLogging', name: str,
                 operating_status: str,
                 pools: List['LoadBalancerPoolReference'],
                 private_ips: List['IP'],
                 profile: 'LoadBalancerProfileReference',
                 provisioning_status: str, public_ips: List['IP'],
                 resource_group: 'ResourceGroupReference',
                 security_groups: List['SecurityGroupReference'],
                 security_groups_supported: bool,
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a LoadBalancer object.

        :param datetime created_at: The date and time that this load balancer was
               created.
        :param str crn: The load balancer's CRN.
        :param str hostname: Fully qualified domain name assigned to this load
               balancer.
        :param str href: The load balancer's canonical URL.
        :param str id: The unique identifier for 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 LoadBalancerLogging logging: The logging configuration for this load
               balancer.
        :param str name: The unique user-defined name for 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 LoadBalancerProfileReference profile: The profile to use for 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.
               Applicable only for public load balancers.
        :param ResourceGroupReference resource_group: The resource group for this
               load balancer.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this load balancer.
               Applicable only for load balancers that support security groups.
        :param bool security_groups_supported: Indicates whether this load balancer
               supports security groups.
        :param List[SubnetReference] subnets: The subnets this load balancer is
               part of.
        """
        self.created_at = created_at
        self.crn = crn
        self.hostname = hostname
        self.href = href
        self.id = id
        self.is_public = is_public
        self.listeners = listeners
        self.logging = logging
        self.name = name
        self.operating_status = operating_status
        self.pools = pools
        self.private_ips = private_ips
        self.profile = profile
        self.provisioning_status = provisioning_status
        self.public_ips = public_ips
        self.resource_group = resource_group
        self.security_groups = security_groups
        self.security_groups_supported = security_groups_supported
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancer':
        """Initialize a LoadBalancer object from a json dictionary."""
        args = {}
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 '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 'logging' in _dict:
            args['logging'] = LoadBalancerLogging.from_dict(
                _dict.get('logging'))
        else:
            raise ValueError(
                'Required property \'logging\' 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 '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 'profile' in _dict:
            args['profile'] = LoadBalancerProfileReference.from_dict(
                _dict.get('profile'))
        else:
            raise ValueError(
                'Required property \'profile\' 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 '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 LoadBalancer JSON'
            )
        if 'security_groups_supported' in _dict:
            args['security_groups_supported'] = _dict.get(
                'security_groups_supported')
        else:
            raise ValueError(
                'Required property \'security_groups_supported\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'hostname') and self.hostname is not None:
            _dict['hostname'] = self.hostname
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'logging') and self.logging is not None:
            _dict['logging'] = self.logging.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, 'profile') and self.profile is not None:
            _dict['profile'] = self.profile.to_dict()
        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,
                   'security_groups') and self.security_groups is not None:
            _dict['security_groups'] = [
                x.to_dict() for x in self.security_groups
            ]
        if hasattr(self, 'security_groups_supported'
                  ) and self.security_groups_supported is not None:
            _dict['security_groups_supported'] = self.security_groups_supported
        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 bool accept_proxy_protocol: If set to `true`, this listener will accept
          and forward PROXY protocol information. Supported by load balancers in the
          `application` family (otherwise always `false`).
    :attr CertificateInstanceReference certificate_instance: (optional) The
          certificate instance used for SSL termination. It is applicable only to `https`
          protocol.
    :attr int connection_limit: (optional) The connection limit of the listener.
    :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 str href: The listener's canonical URL.
    :attr str id: The unique identifier for this load balancer listener.
    :attr List[LoadBalancerListenerPolicyReference] policies: (optional) An array of
          policies for this listener.
    :attr int port: The listener port number, or the inclusive lower bound of the
          port range. Each listener in the load balancer must have a unique `port` and
          `protocol` combination.
    :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`. Each listener in the load balancer must have a unique
          `port` and `protocol` combination.
    :attr str provisioning_status: The provisioning status of this listener.
    """

    def __init__(
            self,
            accept_proxy_protocol: bool,
            created_at: datetime,
            href: str,
            id: str,
            port: int,
            protocol: str,
            provisioning_status: str,
            *,
            certificate_instance: 'CertificateInstanceReference' = None,
            connection_limit: int = None,
            default_pool: 'LoadBalancerPoolReference' = None,
            policies: List['LoadBalancerListenerPolicyReference'] = None
    ) -> None:
        """
        Initialize a LoadBalancerListener object.

        :param bool accept_proxy_protocol: If set to `true`, this listener will
               accept and forward PROXY protocol information. Supported by load balancers
               in the `application` family (otherwise always `false`).
        :param datetime created_at: The date and time that this listener was
               created.
        :param str href: The listener's canonical URL.
        :param str id: The unique identifier for this load balancer listener.
        :param int port: The listener port number, or the inclusive lower bound of
               the port range. Each listener in the load balancer must have a unique
               `port` and `protocol` combination.
        :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`. Each listener in the load balancer must have a
               unique `port` and `protocol` combination.
        :param str provisioning_status: The provisioning status of this listener.
        :param CertificateInstanceReference certificate_instance: (optional) The
               certificate instance used for SSL termination. It is applicable only to
               `https`
               protocol.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolReference default_pool: (optional) The default pool
               associated with the listener.
        :param List[LoadBalancerListenerPolicyReference] policies: (optional) An
               array of policies for this listener.
        """
        self.accept_proxy_protocol = accept_proxy_protocol
        self.certificate_instance = certificate_instance
        self.connection_limit = connection_limit
        self.created_at = created_at
        self.default_pool = default_pool
        self.href = href
        self.id = id
        self.policies = policies
        self.port = port
        self.protocol = protocol
        self.provisioning_status = provisioning_status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListener':
        """Initialize a LoadBalancerListener object from a json dictionary."""
        args = {}
        if 'accept_proxy_protocol' in _dict:
            args['accept_proxy_protocol'] = _dict.get('accept_proxy_protocol')
        else:
            raise ValueError(
                'Required property \'accept_proxy_protocol\' not present in LoadBalancerListener JSON'
            )
        if 'certificate_instance' in _dict:
            args[
                'certificate_instance'] = CertificateInstanceReference.from_dict(
                    _dict.get('certificate_instance'))
        if 'connection_limit' in _dict:
            args['connection_limit'] = _dict.get('connection_limit')
        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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListener JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListener JSON'
            )
        if 'policies' in _dict:
            args['policies'] = [
                LoadBalancerListenerPolicyReference.from_dict(x)
                for x in _dict.get('policies')
            ]
        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 '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, 'accept_proxy_protocol'
                  ) and self.accept_proxy_protocol is not None:
            _dict['accept_proxy_protocol'] = self.accept_proxy_protocol
        if hasattr(self, 'certificate_instance'
                  ) and self.certificate_instance is not None:
            _dict['certificate_instance'] = self.certificate_instance.to_dict()
        if hasattr(self,
                   'connection_limit') and self.connection_limit is not None:
            _dict['connection_limit'] = self.connection_limit
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'policies') and self.policies is not None:
            _dict['policies'] = [x.to_dict() for x in self.policies]
        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,
                '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`. Each
        listener in the load balancer must have a unique `port` and `protocol`
        combination.
        """
        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 LoadBalancerListenerPatch():
    """
    LoadBalancerListenerPatch.

    :attr bool accept_proxy_protocol: (optional) If set to `true`, this listener
          will accept and forward PROXY protocol information. Supported by load balancers
          in the `application` family (otherwise always `false`).
    :attr CertificateInstanceIdentity certificate_instance: (optional) The
          certificate instance used for SSL termination. It is applicable only to `https`
          protocol.
    :attr int connection_limit: (optional) The connection limit of the listener.
    :attr LoadBalancerPoolIdentity default_pool: (optional) The default pool
          associated with the listener. The specified pool must:
          - Belong to this load balancer
          - Have the same `protocol` as this listener
          - Not already be the default pool for another listener.
    :attr int port: (optional) The listener port number, or the inclusive lower
          bound of the port range. Each listener in the load balancer must have a unique
          `port` and `protocol` combination.
    :attr 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`. Each listener in the load balancer must have
          a unique `port` and `protocol` combination.
    """

    def __init__(self,
                 *,
                 accept_proxy_protocol: bool = None,
                 certificate_instance: 'CertificateInstanceIdentity' = None,
                 connection_limit: int = None,
                 default_pool: 'LoadBalancerPoolIdentity' = None,
                 port: int = None,
                 protocol: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPatch object.

        :param bool accept_proxy_protocol: (optional) If set to `true`, this
               listener will accept and forward PROXY protocol information. Supported by
               load balancers in the `application` family (otherwise always `false`).
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance used for SSL termination. It is applicable only to
               `https`
               protocol.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               associated with the listener. The specified pool must:
               - Belong to this load balancer
               - Have the same `protocol` as this listener
               - Not already be the default pool for another listener.
        :param int port: (optional) The listener port number, or the inclusive
               lower bound of the port range. Each listener in the load balancer must have
               a unique `port` and `protocol` combination.
        :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`. Each listener in the load
               balancer must have a unique `port` and `protocol` combination.
        """
        self.accept_proxy_protocol = accept_proxy_protocol
        self.certificate_instance = certificate_instance
        self.connection_limit = connection_limit
        self.default_pool = default_pool
        self.port = port
        self.protocol = protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPatch':
        """Initialize a LoadBalancerListenerPatch object from a json dictionary."""
        args = {}
        if 'accept_proxy_protocol' in _dict:
            args['accept_proxy_protocol'] = _dict.get('accept_proxy_protocol')
        if 'certificate_instance' in _dict:
            args['certificate_instance'] = _dict.get('certificate_instance')
        if 'connection_limit' in _dict:
            args['connection_limit'] = _dict.get('connection_limit')
        if 'default_pool' in _dict:
            args['default_pool'] = _dict.get('default_pool')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'accept_proxy_protocol'
                  ) and self.accept_proxy_protocol is not None:
            _dict['accept_proxy_protocol'] = self.accept_proxy_protocol
        if hasattr(self, 'certificate_instance'
                  ) and self.certificate_instance is not None:
            if isinstance(self.certificate_instance, dict):
                _dict['certificate_instance'] = self.certificate_instance
            else:
                _dict[
                    'certificate_instance'] = self.certificate_instance.to_dict(
                    )
        if hasattr(self,
                   'connection_limit') and self.connection_limit is not None:
            _dict['connection_limit'] = self.connection_limit
        if hasattr(self, 'default_pool') and self.default_pool is not None:
            if isinstance(self.default_pool, dict):
                _dict['default_pool'] = self.default_pool
            else:
                _dict['default_pool'] = self.default_pool.to_dict()
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPatch') -> 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`. Each
        listener in the load balancer must have a unique `port` and `protocol`
        combination.
        """
        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'


class LoadBalancerListenerPolicy():
    """
    LoadBalancerListenerPolicy.

    :attr str action: The policy action.
    :attr datetime created_at: The date and time that this policy was created.
    :attr str href: The listener policy's canonical URL.
    :attr str id: The policy's unique identifier.
    :attr str name: The user-defined name for this policy.
    :attr int priority: Priority of the policy. Lower value indicates higher
          priority.
    :attr str provisioning_status: The provisioning status of this policy.
    :attr List[LoadBalancerListenerPolicyRuleReference] rules: The rules of this
          policy.
    :attr LoadBalancerListenerPolicyTarget target: (optional)
          `LoadBalancerPoolReference` is in the response if `action` is `forward`.
          `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is
          `redirect`.
    """

    def __init__(self,
                 action: str,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 priority: int,
                 provisioning_status: str,
                 rules: List['LoadBalancerListenerPolicyRuleReference'],
                 *,
                 target: 'LoadBalancerListenerPolicyTarget' = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicy object.

        :param str action: The policy action.
        :param datetime created_at: The date and time that this policy was created.
        :param str href: The listener policy's canonical URL.
        :param str id: The policy's unique identifier.
        :param str name: The user-defined name for this policy.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str provisioning_status: The provisioning status of this policy.
        :param List[LoadBalancerListenerPolicyRuleReference] rules: The rules of
               this policy.
        :param LoadBalancerListenerPolicyTarget target: (optional)
               `LoadBalancerPoolReference` is in the response if `action` is `forward`.
               `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is
               `redirect`.
        """
        self.action = action
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.priority = priority
        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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicy JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        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 LoadBalancerListenerPolicyPatch():
    """
    LoadBalancerListenerPolicyPatch.

    :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: (optional) Priority of the policy. Lower value indicates
          higher priority.
    :attr LoadBalancerListenerPolicyTargetPatch 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.
    """

    def __init__(
            self,
            *,
            name: str = None,
            priority: int = None,
            target: 'LoadBalancerListenerPolicyTargetPatch' = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatch object.

        :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 LoadBalancerListenerPolicyTargetPatch 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.
        """
        self.name = name
        self.priority = priority
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyPatch':
        """Initialize a LoadBalancerListenerPolicyPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyPatch object from 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, '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 LoadBalancerListenerPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyPrototype():
    """
    LoadBalancerListenerPolicyPrototype.

    :attr str action: The policy action.
    :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 List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) An array
          of rules for this policy.
    :attr LoadBalancerListenerPolicyTargetPrototype 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,
            action: str,
            priority: int,
            *,
            name: str = None,
            rules: List['LoadBalancerListenerPolicyRulePrototype'] = None,
            target: 'LoadBalancerListenerPolicyTargetPrototype' = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototype object.

        :param str action: The policy action.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :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) An
               array of rules for this policy.
        :param LoadBalancerListenerPolicyTargetPrototype 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.action = action
        self.name = name
        self.priority = priority
        self.rules = rules
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyPrototype':
        """Initialize a LoadBalancerListenerPolicyPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in LoadBalancerListenerPolicyPrototype JSON'
            )
        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 '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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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 LoadBalancerListenerPolicyReference():
    """
    LoadBalancerListenerPolicyReference.

    :attr LoadBalancerListenerPolicyReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The listener policy's canonical URL.
    :attr str id: The policy's unique identifier.
    """

    def __init__(
            self,
            href: str,
            id: str,
            *,
            deleted: 'LoadBalancerListenerPolicyReferenceDeleted' = None
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyReference object.

        :param str href: The listener policy's canonical URL.
        :param str id: The policy's unique identifier.
        :param LoadBalancerListenerPolicyReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyReference':
        """Initialize a LoadBalancerListenerPolicyReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args[
                'deleted'] = LoadBalancerListenerPolicyReferenceDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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 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 LoadBalancerListenerPolicyReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerListenerPolicyReferenceDeleted':
        """Initialize a LoadBalancerListenerPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in LoadBalancerListenerPolicyReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'LoadBalancerListenerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'LoadBalancerListenerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyRule():
    """
    LoadBalancerListenerPolicyRule.

    :attr str condition: The condition of the rule.
    :attr datetime created_at: The date and time that this rule was created.
    :attr str field: (optional) The field. This is applicable to `header`, `query`,
          and `body` rule types.
          If the rule type is `header`, this field is required.
          If the rule type is `query`, this is optional. If specified and the rule
          condition is not
          `matches_regex`, the value must be percent-encoded.
          If the rule type is `body`, this is optional.
    :attr str href: The rule's canonical URL.
    :attr str id: The rule's unique identifier.
    :attr str provisioning_status: The provisioning status of this rule.
    :attr str type: The type of the rule.
          Body rules are applied to form-encoded request bodies using the `UTF-8`
          character set.
    :attr str value: Value to be matched for rule condition.
          If the rule type is `query` and the rule condition is not `matches_regex`, the
          value must be percent-encoded.
    """

    def __init__(self,
                 condition: str,
                 created_at: datetime,
                 href: str,
                 id: str,
                 provisioning_status: str,
                 type: str,
                 value: str,
                 *,
                 field: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRule object.

        :param str condition: The condition of the rule.
        :param datetime created_at: The date and time that this rule was created.
        :param str href: The rule's canonical URL.
        :param str id: The rule's unique identifier.
        :param str provisioning_status: The provisioning status of this rule.
        :param str type: The type of the rule.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this field is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        """
        self.condition = condition
        self.created_at = created_at
        self.field = field
        self.href = href
        self.id = id
        self.provisioning_status = provisioning_status
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRule':
        """Initialize a LoadBalancerListenerPolicyRule object from a json dictionary."""
        args = {}
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        else:
            raise ValueError(
                'Required property \'condition\' 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 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyRule JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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'
            )
        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'
            )
        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, 'condition') and self.condition is not None:
            _dict['condition'] = self.condition
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'field') and self.field is not None:
            _dict['field'] = self.field
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        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 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 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 TypeEnum(str, Enum):
        """
        The type of the rule.
        Body rules are applied to form-encoded request bodies using the `UTF-8` character
        set.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'
        BODY = 'body'


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 LoadBalancerListenerPolicyRulePatch():
    """
    LoadBalancerListenerPolicyRulePatch.

    :attr str condition: (optional) The condition of the rule.
    :attr str field: (optional) The field. This is applicable to `header`, `query`,
          and `body` rule types.
          If the rule type is `header`, this field is required.
          If the rule type is `query`, this is optional. If specified and the rule
          condition is not
          `matches_regex`, the value must be percent-encoded.
          If the rule type is `body`, this is optional.
    :attr str type: (optional) The type of the rule.
          Body rules are applied to form-encoded request bodies using the `UTF-8`
          character set.
    :attr str value: (optional) Value to be matched for rule condition.
          If the rule type is `query` and the rule condition is not `matches_regex`, the
          value must be percent-encoded.
    """

    def __init__(self,
                 *,
                 condition: str = None,
                 field: str = None,
                 type: str = None,
                 value: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePatch object.

        :param str condition: (optional) The condition of the rule.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this field is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        :param str type: (optional) The type of the rule.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: (optional) Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        """
        self.condition = condition
        self.field = field
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRulePatch':
        """Initialize a LoadBalancerListenerPolicyRulePatch object from a json dictionary."""
        args = {}
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        if 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRulePatch object from 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 LoadBalancerListenerPolicyRulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRulePatch') -> 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.
        Body rules are applied to form-encoded request bodies using the `UTF-8` character
        set.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'
        BODY = 'body'


class LoadBalancerListenerPolicyRulePrototype():
    """
    LoadBalancerListenerPolicyRulePrototype.

    :attr str condition: The condition of the rule.
    :attr str field: (optional) The field. This is applicable to `header`, `query`,
          and `body` rule types.
          If the rule type is `header`, this field is required.
          If the rule type is `query`, this is optional. If specified and the rule
          condition is not
          `matches_regex`, the value must be percent-encoded.
          If the rule type is `body`, this is optional.
    :attr str type: The type of the rule.
          Body rules are applied to form-encoded request bodies using the `UTF-8`
          character set.
    :attr str value: Value to be matched for rule condition.
          If the rule type is `query` and the rule condition is not `matches_regex`, the
          value must be percent-encoded.
    """

    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.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this field is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        """
        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.
        Body rules are applied to form-encoded request bodies using the `UTF-8` character
        set.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'
        BODY = 'body'


class LoadBalancerListenerPolicyRuleReference():
    """
    LoadBalancerListenerPolicyRuleReference.

    :attr LoadBalancerListenerPolicyRuleReferenceDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted and
          provides
          some supplementary information.
    :attr str href: The rule's canonical URL.
    :attr str id: The rule's unique identifier.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: 'LoadBalancerListenerPolicyRuleReferenceDeleted' = None
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleReference object.

        :param str href: The rule's canonical URL.
        :param str id: The rule's unique identifier.
        :param LoadBalancerListenerPolicyRuleReferenceDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerListenerPolicyRuleReference':
        """Initialize a LoadBalancerListenerPolicyRuleReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args[
                'deleted'] = LoadBalancerListenerPolicyRuleReferenceDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyRuleReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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 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 LoadBalancerListenerPolicyRuleReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'LoadBalancerListenerPolicyRuleReferenceDeleted':
        """Initialize a LoadBalancerListenerPolicyRuleReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in LoadBalancerListenerPolicyRuleReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRuleReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRuleReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'LoadBalancerListenerPolicyRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'LoadBalancerListenerPolicyRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTarget():
    """
    `LoadBalancerPoolReference` is in the response if `action` is `forward`.
    `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is `redirect`.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference',
                'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetPatch():
    """
    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 LoadBalancerListenerPolicyTargetPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity',
                'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetPrototype():
    """
    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 LoadBalancerListenerPolicyTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity',
                'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPrototypeLoadBalancerContext():
    """
    LoadBalancerListenerPrototypeLoadBalancerContext.

    :attr bool accept_proxy_protocol: (optional) If set to `true`, this listener
          will accept and forward PROXY protocol information. Supported by load balancers
          in the `application` family (otherwise always `false`).
    :attr int connection_limit: (optional) The connection limit of the listener.
    :attr LoadBalancerPoolIdentityByName default_pool: (optional) The default pool
          associated with the listener.
    :attr int port: The listener port number, or the inclusive lower bound of the
          port range. Each listener in the load balancer must have a unique `port` and
          `protocol` combination.
    :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`. Each listener in the load balancer must have a unique
          `port` and `protocol` combination.
    """

    def __init__(self,
                 port: int,
                 protocol: str,
                 *,
                 accept_proxy_protocol: bool = None,
                 connection_limit: int = None,
                 default_pool: 'LoadBalancerPoolIdentityByName' = None) -> None:
        """
        Initialize a LoadBalancerListenerPrototypeLoadBalancerContext object.

        :param int port: The listener port number, or the inclusive lower bound of
               the port range. Each listener in the load balancer must have a unique
               `port` and `protocol` combination.
        :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`. Each listener in the load balancer must have a
               unique `port` and `protocol` combination.
        :param bool accept_proxy_protocol: (optional) If set to `true`, this
               listener will accept and forward PROXY protocol information. Supported by
               load balancers in the `application` family (otherwise always `false`).
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentityByName default_pool: (optional) The default
               pool associated with the listener.
        """
        self.accept_proxy_protocol = accept_proxy_protocol
        self.connection_limit = connection_limit
        self.default_pool = default_pool
        self.port = port
        self.protocol = protocol

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'LoadBalancerListenerPrototypeLoadBalancerContext':
        """Initialize a LoadBalancerListenerPrototypeLoadBalancerContext object from a json dictionary."""
        args = {}
        if 'accept_proxy_protocol' in _dict:
            args['accept_proxy_protocol'] = _dict.get('accept_proxy_protocol')
        if 'connection_limit' in _dict:
            args['connection_limit'] = _dict.get('connection_limit')
        if 'default_pool' in _dict:
            args['default_pool'] = LoadBalancerPoolIdentityByName.from_dict(
                _dict.get('default_pool'))
        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'
            )
        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, 'accept_proxy_protocol'
                  ) and self.accept_proxy_protocol is not None:
            _dict['accept_proxy_protocol'] = self.accept_proxy_protocol
        if hasattr(self,
                   'connection_limit') and self.connection_limit is not None:
            _dict['connection_limit'] = self.connection_limit
        if hasattr(self, 'default_pool') and self.default_pool is not None:
            _dict['default_pool'] = self.default_pool.to_dict()
        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
        return _dict

    def _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`. Each
        listener in the load balancer must have a unique `port` and `protocol`
        combination.
        """
        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'


class LoadBalancerListenerReference():
    """
    LoadBalancerListenerReference.

    :attr LoadBalancerListenerReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The listener's canonical URL.
    :attr str id: The unique identifier for this load balancer listener.
    """

    def __init__(
            self,
            href: str,
            id: str,
            *,
            deleted: 'LoadBalancerListenerReferenceDeleted' = None) -> None:
        """
        Initialize a LoadBalancerListenerReference object.

        :param str href: The listener's canonical URL.
        :param str id: The unique identifier for this load balancer listener.
        :param LoadBalancerListenerReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerReference':
        """Initialize a LoadBalancerListenerReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerListenerReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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 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 LoadBalancerListenerReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a LoadBalancerListenerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerReferenceDeleted':
        """Initialize a LoadBalancerListenerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in LoadBalancerListenerReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerLogging():
    """
    The logging configuration for this load balancer.

    :attr LoadBalancerLoggingDatapath datapath: (optional) The datapath logging
          configuration for this load balancer.
    """

    def __init__(self,
                 *,
                 datapath: 'LoadBalancerLoggingDatapath' = None) -> None:
        """
        Initialize a LoadBalancerLogging object.

        :param LoadBalancerLoggingDatapath datapath: (optional) The datapath
               logging configuration for this load balancer.
        """
        self.datapath = datapath

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerLogging':
        """Initialize a LoadBalancerLogging object from a json dictionary."""
        args = {}
        if 'datapath' in _dict:
            args['datapath'] = LoadBalancerLoggingDatapath.from_dict(
                _dict.get('datapath'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerLogging object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'datapath') and self.datapath is not None:
            _dict['datapath'] = self.datapath.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 LoadBalancerLogging object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerLogging') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerLogging') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerLoggingDatapath():
    """
    The datapath logging configuration for this load balancer.

    :attr bool active: If set to `true`, datapath logging is active for this load
          balancer.
    """

    def __init__(self, active: bool) -> None:
        """
        Initialize a LoadBalancerLoggingDatapath object.

        :param bool active: If set to `true`, datapath logging is active for this
               load balancer.
        """
        self.active = active

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerLoggingDatapath':
        """Initialize a LoadBalancerLoggingDatapath object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        else:
            raise ValueError(
                'Required property \'active\' not present in LoadBalancerLoggingDatapath JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerLoggingDatapath object from 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') and self.active is not None:
            _dict['active'] = self.active
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerLoggingDatapath object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerLoggingDatapath') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerLoggingDatapath') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPatch():
    """
    LoadBalancerPatch.

    :attr LoadBalancerLogging logging: (optional) The logging configuration to use
          for this load balancer.
          To activate logging, the load balancer profile must support the specified
          logging type.
    :attr str name: (optional) The unique user-defined name for this load balancer.
    """

    def __init__(self,
                 *,
                 logging: 'LoadBalancerLogging' = None,
                 name: str = None) -> None:
        """
        Initialize a LoadBalancerPatch object.

        :param LoadBalancerLogging logging: (optional) The logging configuration to
               use for this load balancer.
               To activate logging, the load balancer profile must support the specified
               logging type.
        :param str name: (optional) The unique user-defined name for this load
               balancer.
        """
        self.logging = logging
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPatch':
        """Initialize a LoadBalancerPatch object from a json dictionary."""
        args = {}
        if 'logging' in _dict:
            args['logging'] = LoadBalancerLogging.from_dict(
                _dict.get('logging'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'logging') and self.logging is not None:
            _dict['logging'] = self.logging.to_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 LoadBalancerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPool():
    """
    LoadBalancerPool.

    :attr str algorithm: The load balancing algorithm.
    :attr datetime created_at: The date and time that this pool was created.
    :attr LoadBalancerPoolHealthMonitor health_monitor: The health monitor of this
          pool.
    :attr str href: The pool's canonical URL.
    :attr str id: The unique identifier for this load balancer 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 name: The user-defined name for this load balancer pool.
    :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 str provisioning_status: The provisioning status of this pool.
    :attr str proxy_protocol: The PROXY protocol setting for this pool:
          - `v1`: Enabled with version 1 (human-readable header format)
          - `v2`: Enabled with version 2 (binary header format)
          - `disabled`: Disabled
          Supported by load balancers in the `application` family (otherwise always
          `disabled`).
    :attr LoadBalancerPoolSessionPersistence session_persistence: (optional) The
          session persistence of this 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.
    """

    def __init__(
        self,
        algorithm: str,
        created_at: datetime,
        health_monitor: 'LoadBalancerPoolHealthMonitor',
        href: str,
        id: str,
        name: str,
        protocol: str,
        provisioning_status: str,
        proxy_protocol: str,
        *,
        instance_group: 'InstanceGroupReference' = None,
        members: List['LoadBalancerPoolMemberReference'] = None,
        session_persistence: 'LoadBalancerPoolSessionPersistence' = None
    ) -> None:
        """
        Initialize a LoadBalancerPool object.

        :param str algorithm: The load balancing algorithm.
        :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 href: The pool's canonical URL.
        :param str id: The unique identifier for this load balancer pool.
        :param str name: The user-defined name for this load balancer pool.
        :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 str provisioning_status: The provisioning status of this pool.
        :param str proxy_protocol: The PROXY protocol setting for this pool:
               - `v1`: Enabled with version 1 (human-readable header format)
               - `v2`: Enabled with version 2 (binary header format)
               - `disabled`: Disabled
               Supported by load balancers in the `application` family (otherwise always
               `disabled`).
        :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.
               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.
        """
        self.algorithm = algorithm
        self.created_at = created_at
        self.health_monitor = health_monitor
        self.href = href
        self.id = id
        self.instance_group = instance_group
        self.members = members
        self.name = name
        self.protocol = protocol
        self.provisioning_status = provisioning_status
        self.proxy_protocol = proxy_protocol
        self.session_persistence = session_persistence

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPool':
        """Initialize a LoadBalancerPool object from a json dictionary."""
        args = {}
        if 'algorithm' in _dict:
            args['algorithm'] = _dict.get('algorithm')
        else:
            raise ValueError(
                'Required property \'algorithm\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPool JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancerPool JSON'
            )
        if 'proxy_protocol' in _dict:
            args['proxy_protocol'] = _dict.get('proxy_protocol')
        else:
            raise ValueError(
                'Required property \'proxy_protocol\' 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, 'algorithm') and self.algorithm is not None:
            _dict['algorithm'] = self.algorithm
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(
                self,
                'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        if hasattr(self, 'proxy_protocol') and self.proxy_protocol is not None:
            _dict['proxy_protocol'] = self.proxy_protocol
        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 ProxyProtocolEnum(str, Enum):
        """
        The PROXY protocol setting for this pool:
        - `v1`: Enabled with version 1 (human-readable header format)
        - `v2`: Enabled with version 2 (binary header format)
        - `disabled`: Disabled
        Supported by load balancers in the `application` family (otherwise always
        `disabled`).
        """
        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'


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 path. Applicable only if the
          health monitor `type` is `http` or
          `https`. This value must be in the format of an [origin-form request
          target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
    """

    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 path. Applicable only
               if the health monitor `type` is `http` or
               `https`. This value must be in the format of an [origin-form request
               target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
        """
        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 path. Applicable only if the
          health monitor `type` is `http` or
          `https`. This value must be in the format of an [origin-form request
          target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
    """

    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 path. Applicable only
               if the health monitor `type` is `http` or
               `https`. This value must be in the format of an [origin-form request
               target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
        """
        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 path. Applicable only if the
          health monitor `type` is `http` or
          `https`. This value must be in the format of an [origin-form request
          target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
    """

    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 path. Applicable only
               if the health monitor `type` is `http` or
               `https`. This value must be in the format of an [origin-form request
               target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
        """
        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 datetime created_at: The date and time that this member was created.
    :attr str health: Health of the server member in the pool.
    :attr str href: The member's canonical URL.
    :attr str id: The unique identifier for this load balancer pool member.
    :attr int port: The port number of the application running in the server member.
    :attr str provisioning_status: The provisioning status of this member.
    :attr LoadBalancerPoolMemberTarget target: The pool member target. Load
          balancers in the `network` family support virtual server
          instances. Load balancers in the `application` family support IP addresses.
    :attr int weight: (optional) Weight of the server member. Applicable only if the
          pool algorithm is
          `weighted_round_robin`.
    """

    def __init__(self,
                 created_at: datetime,
                 health: str,
                 href: str,
                 id: str,
                 port: int,
                 provisioning_status: str,
                 target: 'LoadBalancerPoolMemberTarget',
                 *,
                 weight: int = None) -> None:
        """
        Initialize a LoadBalancerPoolMember object.

        :param datetime created_at: The date and time that this member was created.
        :param str health: Health of the server member in the pool.
        :param str href: The member's canonical URL.
        :param str id: The unique identifier for this load balancer pool member.
        :param int port: The port number of the application running in the server
               member.
        :param str provisioning_status: The provisioning status of this member.
        :param LoadBalancerPoolMemberTarget target: The pool member target. Load
               balancers in the `network` family support virtual server
               instances. Load balancers in the `application` family support IP addresses.
        :param int weight: (optional) Weight of the server member. Applicable only
               if the pool algorithm is
               `weighted_round_robin`.
        """
        self.created_at = created_at
        self.health = health
        self.href = href
        self.id = id
        self.port = port
        self.provisioning_status = provisioning_status
        self.target = target
        self.weight = weight

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMember':
        """Initialize a LoadBalancerPoolMember object from a json dictionary."""
        args = {}
        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 'health' in _dict:
            args['health'] = _dict.get('health')
        else:
            raise ValueError(
                'Required property \'health\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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'
            )
        if 'weight' in _dict:
            args['weight'] = _dict.get('weight')
        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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'health') and self.health is not None:
            _dict['health'] = self.health
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        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()
        if hasattr(self, 'weight') and self.weight is not None:
            _dict['weight'] = self.weight
        return _dict

    def _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 LoadBalancerPoolMemberPatch():
    """
    LoadBalancerPoolMemberPatch.

    :attr int port: (optional) The port number of the application running in the
          server member.
    :attr LoadBalancerPoolMemberTargetPrototype target: (optional) The pool member
          target. Load balancers in the `network` family support virtual server
          instances. Load balancers in the `application` family support IP addresses.
    :attr int weight: (optional) Weight of the server member. Applicable only if the
          pool algorithm is
          `weighted_round_robin`.
    """

    def __init__(self,
                 *,
                 port: int = None,
                 target: 'LoadBalancerPoolMemberTargetPrototype' = None,
                 weight: int = None) -> None:
        """
        Initialize a LoadBalancerPoolMemberPatch object.

        :param int port: (optional) The port number of the application running in
               the server member.
        :param LoadBalancerPoolMemberTargetPrototype target: (optional) The pool
               member target. Load balancers in the `network` family support virtual
               server
               instances. Load balancers in the `application` family support IP addresses.
        :param int weight: (optional) Weight of the server member. Applicable only
               if the pool algorithm is
               `weighted_round_robin`.
        """
        self.port = port
        self.target = target
        self.weight = weight

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberPatch':
        """Initialize a LoadBalancerPoolMemberPatch object from a json dictionary."""
        args = {}
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        if 'weight' in _dict:
            args['weight'] = _dict.get('weight')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberPatch object from 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, '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, 'weight') and self.weight is not None:
            _dict['weight'] = self.weight
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberPatch') -> 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 LoadBalancerPoolMemberTargetPrototype target: The pool member target. Load
          balancers in the `network` family support virtual server
          instances. Load balancers in the `application` family support IP addresses.
    :attr int weight: (optional) Weight of the server member. Applicable only if the
          pool algorithm is
          `weighted_round_robin`.
    """

    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 virtual server
               instances. Load balancers in the `application` family support IP addresses.
        :param int weight: (optional) Weight of the server member. Applicable only
               if the pool algorithm is
               `weighted_round_robin`.
        """
        self.port = port
        self.target = target
        self.weight = weight

    @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 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError(
                'Required property \'target\' not present in LoadBalancerPoolMemberPrototype JSON'
            )
        if 'weight' in _dict:
            args['weight'] = _dict.get('weight')
        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, '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, 'weight') and self.weight is not None:
            _dict['weight'] = self.weight
        return _dict

    def _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 LoadBalancerPoolMemberReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The member's canonical URL.
    :attr str id: The unique identifier for this load balancer pool member.
    """

    def __init__(
            self,
            href: str,
            id: str,
            *,
            deleted: 'LoadBalancerPoolMemberReferenceDeleted' = None) -> None:
        """
        Initialize a LoadBalancerPoolMemberReference object.

        :param str href: The member's canonical URL.
        :param str id: The unique identifier for this load balancer pool member.
        :param LoadBalancerPoolMemberReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberReference':
        """Initialize a LoadBalancerPoolMemberReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerPoolMemberReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolMemberReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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 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 LoadBalancerPoolMemberReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a LoadBalancerPoolMemberReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberReferenceDeleted':
        """Initialize a LoadBalancerPoolMemberReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in LoadBalancerPoolMemberReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberReferenceDeleted') -> 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 virtual server
    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 virtual server
    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 LoadBalancerPoolPatch():
    """
    LoadBalancerPoolPatch.

    :attr str algorithm: (optional) The load balancing algorithm.
    :attr LoadBalancerPoolHealthMonitorPatch health_monitor: (optional) The health
          monitor of this pool.
    :attr str name: (optional) The user-defined name for this load balancer pool.
    :attr 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.
    :attr str proxy_protocol: (optional) The PROXY protocol setting for this pool:
          - `v1`: Enabled with version 1 (human-readable header format)
          - `v2`: Enabled with version 2 (binary header format)
          - `disabled`: Disabled
          Supported by load balancers in the `application` family (otherwise always
          `disabled`).
    :attr LoadBalancerPoolSessionPersistencePatch session_persistence: (optional)
          The session persistence of this pool.
    """

    def __init__(
        self,
        *,
        algorithm: str = None,
        health_monitor: 'LoadBalancerPoolHealthMonitorPatch' = None,
        name: str = None,
        protocol: str = None,
        proxy_protocol: str = None,
        session_persistence: 'LoadBalancerPoolSessionPersistencePatch' = None
    ) -> None:
        """
        Initialize a LoadBalancerPoolPatch object.

        :param str algorithm: (optional) The load balancing algorithm.
        :param LoadBalancerPoolHealthMonitorPatch health_monitor: (optional) The
               health monitor of this pool.
        :param str name: (optional) The user-defined name for this load balancer
               pool.
        :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 str proxy_protocol: (optional) The PROXY protocol setting for this
               pool:
               - `v1`: Enabled with version 1 (human-readable header format)
               - `v2`: Enabled with version 2 (binary header format)
               - `disabled`: Disabled
               Supported by load balancers in the `application` family (otherwise always
               `disabled`).
        :param LoadBalancerPoolSessionPersistencePatch session_persistence:
               (optional) The session persistence of this pool.
        """
        self.algorithm = algorithm
        self.health_monitor = health_monitor
        self.name = name
        self.protocol = protocol
        self.proxy_protocol = proxy_protocol
        self.session_persistence = session_persistence

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolPatch':
        """Initialize a LoadBalancerPoolPatch object from a json dictionary."""
        args = {}
        if 'algorithm' in _dict:
            args['algorithm'] = _dict.get('algorithm')
        if 'health_monitor' in _dict:
            args[
                'health_monitor'] = LoadBalancerPoolHealthMonitorPatch.from_dict(
                    _dict.get('health_monitor'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'proxy_protocol' in _dict:
            args['proxy_protocol'] = _dict.get('proxy_protocol')
        if 'session_persistence' in _dict:
            args[
                'session_persistence'] = LoadBalancerPoolSessionPersistencePatch.from_dict(
                    _dict.get('session_persistence'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'algorithm') and self.algorithm is not None:
            _dict['algorithm'] = self.algorithm
        if hasattr(self, 'health_monitor') and self.health_monitor is not None:
            _dict['health_monitor'] = self.health_monitor.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'proxy_protocol') and self.proxy_protocol is not None:
            _dict['proxy_protocol'] = self.proxy_protocol
        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 LoadBalancerPoolPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolPatch') -> 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 ProxyProtocolEnum(str, Enum):
        """
        The PROXY protocol setting for this pool:
        - `v1`: Enabled with version 1 (human-readable header format)
        - `v2`: Enabled with version 2 (binary header format)
        - `disabled`: Disabled
        Supported by load balancers in the `application` family (otherwise always
        `disabled`).
        """
        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'


class LoadBalancerPoolPrototype():
    """
    LoadBalancerPoolPrototype.

    :attr str algorithm: The load balancing algorithm.
    :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 pool member of any other load
          balancer in the same VPC.
    :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 protocol: The protocol used for this load balancer pool. Load
          balancers in the `network` family support `tcp`. Load balancers in the
          `application` family support `tcp`, `http`, and
          `https`.
    :attr str proxy_protocol: (optional) The PROXY protocol setting for this pool:
          - `v1`: Enabled with version 1 (human-readable header format)
          - `v2`: Enabled with version 2 (binary header format)
          - `disabled`: Disabled
          Supported by load balancers in the `application` family (otherwise always
          `disabled`).
    :attr LoadBalancerPoolSessionPersistencePrototype session_persistence:
          (optional) The session persistence of this pool.
    """

    def __init__(
        self,
        algorithm: str,
        health_monitor: 'LoadBalancerPoolHealthMonitorPrototype',
        protocol: str,
        *,
        members: List['LoadBalancerPoolMemberPrototype'] = None,
        name: str = None,
        proxy_protocol: str = None,
        session_persistence: 'LoadBalancerPoolSessionPersistencePrototype' = None
    ) -> None:
        """
        Initialize a LoadBalancerPoolPrototype object.

        :param str algorithm: The load balancing algorithm.
        :param LoadBalancerPoolHealthMonitorPrototype health_monitor: The health
               monitor of this pool.
        :param str protocol: The protocol used for this load balancer pool. Load
               balancers in the `network` family support `tcp`. Load balancers in the
               `application` family support `tcp`, `http`, and
               `https`.
        :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 pool
               member of any other load balancer in the same VPC.
        :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 str proxy_protocol: (optional) The PROXY protocol setting for this
               pool:
               - `v1`: Enabled with version 1 (human-readable header format)
               - `v2`: Enabled with version 2 (binary header format)
               - `disabled`: Disabled
               Supported by load balancers in the `application` family (otherwise always
               `disabled`).
        :param LoadBalancerPoolSessionPersistencePrototype session_persistence:
               (optional) The session persistence of this pool.
        """
        self.algorithm = algorithm
        self.health_monitor = health_monitor
        self.members = members
        self.name = name
        self.protocol = protocol
        self.proxy_protocol = proxy_protocol
        self.session_persistence = session_persistence

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolPrototype':
        """Initialize a LoadBalancerPoolPrototype object from a json dictionary."""
        args = {}
        if 'algorithm' in _dict:
            args['algorithm'] = _dict.get('algorithm')
        else:
            raise ValueError(
                'Required property \'algorithm\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in LoadBalancerPoolPrototype JSON'
            )
        if 'proxy_protocol' in _dict:
            args['proxy_protocol'] = _dict.get('proxy_protocol')
        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, 'algorithm') and self.algorithm is not None:
            _dict['algorithm'] = self.algorithm
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'proxy_protocol') and self.proxy_protocol is not None:
            _dict['proxy_protocol'] = self.proxy_protocol
        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. Load balancers in the `network`
        family support `tcp`. Load balancers in the `application` family support `tcp`,
        `http`, and
        `https`.
        """
        HTTP = 'http'
        TCP = 'tcp'
        HTTPS = 'https'

    class ProxyProtocolEnum(str, Enum):
        """
        The PROXY protocol setting for this pool:
        - `v1`: Enabled with version 1 (human-readable header format)
        - `v2`: Enabled with version 2 (binary header format)
        - `disabled`: Disabled
        Supported by load balancers in the `application` family (otherwise always
        `disabled`).
        """
        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'


class LoadBalancerPoolReference():
    """
    LoadBalancerPoolReference.

    :attr LoadBalancerPoolReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The pool's canonical URL.
    :attr str id: The unique identifier for this load balancer pool.
    :attr str name: The user-defined name for this load balancer pool.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'LoadBalancerPoolReferenceDeleted' = None) -> None:
        """
        Initialize a LoadBalancerPoolReference object.

        :param str href: The pool's canonical URL.
        :param str id: The unique identifier for this load balancer pool.
        :param str name: The user-defined name for this load balancer pool.
        :param LoadBalancerPoolReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolReference':
        """Initialize a LoadBalancerPoolReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerPoolReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 LoadBalancerPoolReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a LoadBalancerPoolReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolReferenceDeleted':
        """Initialize a LoadBalancerPoolReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in LoadBalancerPoolReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolReferenceDeleted') -> 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 family: The product family this load balancer profile belongs to.
    :attr str href: The URL for this load balancer profile.
    :attr LoadBalancerProfileLoggingSupported logging_supported: Indicates which
          logging type(s) are supported for a load balancer with this profile.
    :attr str name: The globally unique name for this load balancer profile.
    :attr LoadBalancerProfileSecurityGroupsSupported security_groups_supported:
    """

    def __init__(
        self, family: str, href: str,
        logging_supported: 'LoadBalancerProfileLoggingSupported', name: str,
        security_groups_supported: 'LoadBalancerProfileSecurityGroupsSupported'
    ) -> None:
        """
        Initialize a LoadBalancerProfile object.

        :param str family: The product family this load balancer profile belongs
               to.
        :param str href: The URL for this load balancer profile.
        :param LoadBalancerProfileLoggingSupported logging_supported: Indicates
               which logging type(s) are supported for a load balancer with this profile.
        :param str name: The globally unique name for this load balancer profile.
        :param LoadBalancerProfileSecurityGroupsSupported
               security_groups_supported:
        """
        self.family = family
        self.href = href
        self.logging_supported = logging_supported
        self.name = name
        self.security_groups_supported = security_groups_supported

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfile':
        """Initialize a LoadBalancerProfile object from a json dictionary."""
        args = {}
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' 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 'logging_supported' in _dict:
            args[
                'logging_supported'] = LoadBalancerProfileLoggingSupported.from_dict(
                    _dict.get('logging_supported'))
        else:
            raise ValueError(
                'Required property \'logging_supported\' not present in LoadBalancerProfile JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerProfile JSON'
            )
        if 'security_groups_supported' in _dict:
            args['security_groups_supported'] = _dict.get(
                'security_groups_supported')
        else:
            raise ValueError(
                'Required property \'security_groups_supported\' 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, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self,
                   'logging_supported') and self.logging_supported is not None:
            _dict['logging_supported'] = self.logging_supported.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'security_groups_supported'
                  ) and self.security_groups_supported is not None:
            if isinstance(self.security_groups_supported, dict):
                _dict[
                    'security_groups_supported'] = self.security_groups_supported
            else:
                _dict[
                    'security_groups_supported'] = self.security_groups_supported.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 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 link 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 link to the next page
          of resources. This property is present for all pages
          except the last page.
    :attr List[LoadBalancerProfile] profiles: Collection of load balancer profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'LoadBalancerProfileCollectionFirst',
                 limit: int,
                 profiles: List['LoadBalancerProfile'],
                 total_count: int,
                 *,
                 next: 'LoadBalancerProfileCollectionNext' = None) -> None:
        """
        Initialize a LoadBalancerProfileCollection object.

        :param LoadBalancerProfileCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[LoadBalancerProfile] profiles: Collection of load balancer
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param LoadBalancerProfileCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.profiles = profiles
        self.total_count = total_count

    @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 '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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, 'profiles') and self.profiles is not None:
            _dict['profiles'] = [x.to_dict() for x in self.profiles]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerProfileCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerProfileCollectionNext object.

        :param str href: The URL for a 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 LoadBalancerProfileLoggingSupported():
    """
    Indicates which logging type(s) are supported for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr List[str] value: The supported logging type(s) for a load balancer with
          this profile.
    """

    def __init__(self, type: str, value: List[str]) -> None:
        """
        Initialize a LoadBalancerProfileLoggingSupported object.

        :param str type: The type for this profile field.
        :param List[str] value: The supported logging type(s) for a load balancer
               with this profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileLoggingSupported':
        """Initialize a LoadBalancerProfileLoggingSupported object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerProfileLoggingSupported JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in LoadBalancerProfileLoggingSupported JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileLoggingSupported object from 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 LoadBalancerProfileLoggingSupported object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileLoggingSupported') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileLoggingSupported') -> 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 LoadBalancerProfileReference():
    """
    LoadBalancerProfileReference.

    :attr str family: The product family this load balancer profile belongs to.
    :attr str href: The URL for this load balancer profile.
    :attr str name: The globally unique name for this load balancer profile.
    """

    def __init__(self, family: str, href: str, name: str) -> None:
        """
        Initialize a LoadBalancerProfileReference object.

        :param str family: The product family this load balancer profile belongs
               to.
        :param str href: The URL for this load balancer profile.
        :param str name: The globally unique name for this load balancer profile.
        """
        self.family = family
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileReference':
        """Initialize a LoadBalancerProfileReference object from a json dictionary."""
        args = {}
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError(
                'Required property \'family\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'family') and self.family is not None:
            _dict['family'] = self.family
        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 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 LoadBalancerProfileSecurityGroupsSupported():
    """
    LoadBalancerProfileSecurityGroupsSupported.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerProfileSecurityGroupsSupported object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerProfileSecurityGroupsSupportedFixed',
                'LoadBalancerProfileSecurityGroupsSupportedDependent'
            ]))
        raise Exception(msg)


class LoadBalancerReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a LoadBalancerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerReferenceDeleted':
        """Initialize a LoadBalancerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in LoadBalancerReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerReferenceDeleted') -> 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 datetime created_at: The date and time that the network ACL was created.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str id: The unique identifier for this network ACL.
    :attr str name: The user-defined name for this network ACL.
    :attr ResourceGroupReference resource_group: The resource group for this network
          ACL.
    :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.
    :attr VPCReference vpc: The VPC this network ACL is a part of.
    """

    def __init__(self, created_at: datetime, crn: str, href: str, id: str,
                 name: str, resource_group: 'ResourceGroupReference',
                 rules: List['NetworkACLRuleItem'],
                 subnets: List['SubnetReference'], vpc: 'VPCReference') -> None:
        """
        Initialize a NetworkACL object.

        :param datetime created_at: The date and time that the network ACL was
               created.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str id: The unique identifier for this network ACL.
        :param str name: The user-defined name for this network ACL.
        :param ResourceGroupReference resource_group: The resource group for this
               network ACL.
        :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.
        :param VPCReference vpc: The VPC this network ACL is a part of.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.subnets = subnets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACL':
        """Initialize a NetworkACL object from a json dictionary."""
        args = {}
        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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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 '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')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError(
                'Required property \'vpc\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, '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, 'resource_group') and self.resource_group is not None:
            _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]
        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 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 link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[NetworkACL] network_acls: Collection of network ACLs.
    :attr NetworkACLCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'NetworkACLCollectionFirst',
                 limit: int,
                 network_acls: List['NetworkACL'],
                 total_count: int,
                 *,
                 next: 'NetworkACLCollectionNext' = None) -> None:
        """
        Initialize a NetworkACLCollection object.

        :param NetworkACLCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[NetworkACL] network_acls: Collection of network ACLs.
        :param int total_count: The total number of resources across all pages.
        :param NetworkACLCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.network_acls = network_acls
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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, 'network_acls') and self.network_acls is not None:
            _dict['network_acls'] = [x.to_dict() for x in self.network_acls]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLCollectionNext object.

        :param str href: The URL for a 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 NetworkACLPatch():
    """
    NetworkACLPatch.

    :attr str name: (optional) The user-defined name for this network ACL. Names
          must be unique within the VPC the network ACL resides in.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a NetworkACLPatch object.

        :param str name: (optional) The user-defined name for this network ACL.
               Names must be unique within the VPC the network ACL resides in.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLPatch':
        """Initialize a NetworkACLPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLPatch object from 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 NetworkACLPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 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 this network ACL is to be a part of.
    """

    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 crn: The CRN for this network ACL.
    :attr NetworkACLReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this network ACL.
    :attr str id: The unique identifier for this network ACL.
    :attr str name: The user-defined name for this network ACL.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'NetworkACLReferenceDeleted' = None) -> None:
        """
        Initialize a NetworkACLReference object.

        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str id: The unique identifier for this network ACL.
        :param str name: The user-defined name for this network ACL.
        :param NetworkACLReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLReference':
        """Initialize a NetworkACLReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in NetworkACLReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = NetworkACLReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 NetworkACLReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a NetworkACLReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLReferenceDeleted':
        """Initialize a NetworkACLReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in NetworkACLReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRule():
    """
    NetworkACLRule.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 protocol: The protocol to enforce.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    """

    def __init__(self,
                 action: str,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 protocol: str,
                 source: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRule object.

        :param str action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 protocol: The protocol to enforce.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRuleBeforePatch():
    """
    The rule to move this rule immediately before. Specify `null` to move this rule after
    all existing rules.

    """

    def __init__(self) -> None:
        """
        Initialize a NetworkACLRuleBeforePatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById',
                'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref'
            ]))
        raise Exception(msg)


class NetworkACLRuleBeforePrototype():
    """
    The rule to insert this rule immediately before. If omitted, this rule will be
    inserted after all existing rules.

    """

    def __init__(self) -> None:
        """
        Initialize a NetworkACLRuleBeforePrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById',
                'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref'
            ]))
        raise Exception(msg)


class NetworkACLRuleCollection():
    """
    NetworkACLRuleCollection.

    :attr NetworkACLRuleCollectionFirst first: A link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[NetworkACLRuleItem] rules: Ordered collection of network ACL rules.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'NetworkACLRuleCollectionFirst',
                 limit: int,
                 rules: List['NetworkACLRuleItem'],
                 total_count: int,
                 *,
                 next: 'NetworkACLRuleCollectionNext' = None) -> None:
        """
        Initialize a NetworkACLRuleCollection object.

        :param NetworkACLRuleCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[NetworkACLRuleItem] rules: Ordered collection of network ACL
               rules.
        :param int total_count: The total number of resources across all pages.
        :param NetworkACLRuleCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.rules = rules
        self.total_count = total_count

    @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 '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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, 'rules') and self.rules is not None:
            _dict['rules'] = [x.to_dict() for x in self.rules]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleCollectionNext object.

        :param str href: The URL for a 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 NetworkACLRuleItem():
    """
    NetworkACLRuleItem.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 protocol: The protocol to enforce.
    :attr str source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    """

    def __init__(self,
                 action: str,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 protocol: str,
                 source: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRuleItem object.

        :param str action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 protocol: The protocol to enforce.
        :param str source: The source CIDR block. The CIDR block `0.0.0.0/0`
               applies to all addresses.
        :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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'


class NetworkACLRulePatch():
    """
    NetworkACLRulePatch.

    :attr str action: (optional) Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePatch before: (optional) The rule to move this rule
          immediately before. Specify `null` to move this rule after
          all existing rules.
    :attr int code: (optional) The ICMP traffic code to allow.
    :attr str destination: (optional) The destination IP address or CIDR block. The
          CIDR block `0.0.0.0/0` applies to all addresses.
    :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 str direction: (optional) Whether the traffic to be matched is `inbound`
          or `outbound`.
    :attr str name: (optional) The user-defined name for this rule. Names must be
          unique within the network ACL the rule resides in.
    :attr str source: (optional) The source IP address or CIDR block.  The CIDR
          block `0.0.0.0/0` applies to all addresses.
    :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.
    :attr int type: (optional) The ICMP traffic type to allow.
    """

    def __init__(self,
                 *,
                 action: str = None,
                 before: 'NetworkACLRuleBeforePatch' = None,
                 code: int = None,
                 destination: str = None,
                 destination_port_max: int = None,
                 destination_port_min: int = None,
                 direction: str = None,
                 name: str = None,
                 source: str = None,
                 source_port_max: int = None,
                 source_port_min: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRulePatch object.

        :param str action: (optional) Whether to allow or deny matching traffic.
        :param NetworkACLRuleBeforePatch before: (optional) The rule to move this
               rule immediately before. Specify `null` to move this rule after
               all existing rules.
        :param int code: (optional) The ICMP traffic code to allow.
        :param str destination: (optional) The destination 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 str direction: (optional) Whether the traffic to be matched is
               `inbound` or `outbound`.
        :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 source: (optional) The source IP address or CIDR block.  The
               CIDR block `0.0.0.0/0` applies to all addresses.
        :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 type: (optional) The ICMP traffic type to allow.
        """
        self.action = action
        self.before = before
        self.code = code
        self.destination = destination
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.direction = direction
        self.name = name
        self.source = source
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePatch':
        """Initialize a NetworkACLRulePatch object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        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 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        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')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePatch object from 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, '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, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        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, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        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
        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 NetworkACLRulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePatch') -> 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 NetworkACLRulePrototype():
    """
    NetworkACLRulePrototype.

    :attr str action: Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePrototype before: (optional) The rule to insert this
          rule immediately before. If omitted, this rule will be
          inserted after all existing rules.
    :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 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 protocol: The protocol to enforce.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 protocol: str,
                 source: str,
                 *,
                 before: 'NetworkACLRuleBeforePrototype' = None,
                 name: str = 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 protocol: The protocol to enforce.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :param NetworkACLRuleBeforePrototype before: (optional) The rule to insert
               this rule immediately before. If omitted, this rule will be
               inserted after all existing rules.
        :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([
                '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 NetworkACLRulePrototypeNetworkACLContext():
    """
    NetworkACLRulePrototypeNetworkACLContext.

    :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 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 protocol: The protocol to enforce.
    :attr str source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    """

    def __init__(self,
                 action: str,
                 destination: str,
                 direction: str,
                 protocol: str,
                 source: 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 protocol: The protocol to enforce.
        :param str source: The source IP address or CIDR block.  The CIDR block
               `0.0.0.0/0` applies to all addresses.
        :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 NetworkACLRuleReference():
    """
    NetworkACLRuleReference.

    :attr NetworkACLRuleReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str name: The user-defined name for this network ACL rule.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'NetworkACLRuleReferenceDeleted' = None) -> None:
        """
        Initialize a NetworkACLRuleReference object.

        :param str href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str name: The user-defined name for this network ACL rule.
        :param NetworkACLRuleReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleReference':
        """Initialize a NetworkACLRuleReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkACLRuleReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 NetworkACLRuleReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a NetworkACLRuleReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleReferenceDeleted':
        """Initialize a NetworkACLRuleReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in NetworkACLRuleReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterface():
    """
    NetworkInterface.

    :attr bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed on
          this interface. If false, source IP spoofing is prevented on this interface. If
          true, source IP spoofing is allowed on this interface.
    :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 str href: The URL for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str name: The user-defined name for this network interface.
    :attr int port_speed: The network interface port speed in Mbps.
    :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 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,
                 allow_ip_spoofing: bool,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 port_speed: int,
                 primary_ipv4_address: str,
                 resource_type: str,
                 security_groups: List['SecurityGroupReference'],
                 status: str,
                 subnet: 'SubnetReference',
                 type: str,
                 *,
                 floating_ips: List['FloatingIPReference'] = None) -> None:
        """
        Initialize a NetworkInterface object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this interface. If false, source IP spoofing is prevented on
               this interface. If true, source IP spoofing is allowed on this interface.
        :param datetime created_at: The date and time that the network interface
               was created.
        :param str href: The URL for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str name: The user-defined name for this network interface.
        :param int port_speed: The network interface port speed in Mbps.
        :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 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.allow_ip_spoofing = allow_ip_spoofing
        self.created_at = created_at
        self.floating_ips = floating_ips
        self.href = href
        self.id = id
        self.name = name
        self.port_speed = port_speed
        self.primary_ipv4_address = primary_ipv4_address
        self.resource_type = resource_type
        self.security_groups = security_groups
        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 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        else:
            raise ValueError(
                'Required property \'allow_ip_spoofing\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in NetworkInterface JSON'
            )
        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 '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 '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,
                   'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'port_speed') and self.port_speed is not None:
            _dict['port_speed'] = self.port_speed
        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, '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'
        DELETING = 'deleting'
        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 link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[NetworkInterface] network_interfaces: Collection of network
          interfaces.
    :attr NetworkInterfaceCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'NetworkInterfaceCollectionFirst',
                 limit: int,
                 network_interfaces: List['NetworkInterface'],
                 total_count: int,
                 *,
                 next: 'NetworkInterfaceCollectionNext' = None) -> None:
        """
        Initialize a NetworkInterfaceCollection object.

        :param NetworkInterfaceCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[NetworkInterface] network_interfaces: Collection of network
               interfaces.
        :param int total_count: The total number of resources across all pages.
        :param NetworkInterfaceCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.network_interfaces = network_interfaces
        self.next = next
        self.total_count = total_count

    @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 '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'
            )
        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'
            )
        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,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        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
        return _dict

    def _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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkInterfaceCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkInterfaceCollectionNext object.

        :param str href: The URL for a 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 NetworkInterfaceInstanceContextReferenceDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted and
          provides
          some supplementary information.
    :attr str href: The URL for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str name: The user-defined name 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,
        href: str,
        id: str,
        name: str,
        primary_ipv4_address: str,
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: 'NetworkInterfaceInstanceContextReferenceDeleted' = None
    ) -> None:
        """
        Initialize a NetworkInterfaceInstanceContextReference object.

        :param str href: The URL for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str name: The user-defined name 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.
        :param NetworkInterfaceInstanceContextReferenceDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        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 'deleted' in _dict:
            args[
                'deleted'] = NetworkInterfaceInstanceContextReferenceDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 NetworkInterfaceInstanceContextReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a NetworkInterfaceInstanceContextReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkInterfaceInstanceContextReferenceDeleted':
        """Initialize a NetworkInterfaceInstanceContextReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in NetworkInterfaceInstanceContextReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceInstanceContextReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceInstanceContextReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'NetworkInterfaceInstanceContextReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'NetworkInterfaceInstanceContextReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfacePatch():
    """
    NetworkInterfacePatch.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this interface. If false, source IP spoofing is prevented on this
          interface. If true, source IP spoofing is allowed on this interface.
    :attr str name: (optional) The user-defined name for this network interface.
    """

    def __init__(self,
                 *,
                 allow_ip_spoofing: bool = None,
                 name: str = None) -> None:
        """
        Initialize a NetworkInterfacePatch object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If false, source IP spoofing is
               prevented on this interface. If true, source IP spoofing is allowed on this
               interface.
        :param str name: (optional) The user-defined name for this network
               interface.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfacePatch':
        """Initialize a NetworkInterfacePatch object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfacePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self,
                   'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        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 NetworkInterfacePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfacePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfacePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfacePrototype():
    """
    NetworkInterfacePrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this interface. If false, source IP spoofing is prevented on this
          interface. If true, source IP spoofing is allowed on this interface.
    :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',
                 *,
                 allow_ip_spoofing: bool = None,
                 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 bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If false, source IP spoofing is
               prevented on this interface. If true, source IP spoofing is allowed on this
               interface.
        :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.allow_ip_spoofing = allow_ip_spoofing
        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 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        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,
                   'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        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 NetworkInterfaceReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str name: The user-defined name for this network interface.
    :attr str primary_ipv4_address: The primary IPv4 address.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 primary_ipv4_address: str,
                 resource_type: str,
                 *,
                 deleted: 'NetworkInterfaceReferenceDeleted' = None) -> None:
        """
        Initialize a NetworkInterfaceReference object.

        :param str href: The URL for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str name: The user-defined name for this network interface.
        :param str primary_ipv4_address: The primary IPv4 address.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        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 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 NetworkInterfaceReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a NetworkInterfaceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceReferenceDeleted':
        """Initialize a NetworkInterfaceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in NetworkInterfaceReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceReferenceTargetContextDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a NetworkInterfaceReferenceTargetContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkInterfaceReferenceTargetContextDeleted':
        """Initialize a NetworkInterfaceReferenceTargetContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in NetworkInterfaceReferenceTargetContextDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceReferenceTargetContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceReferenceTargetContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'NetworkInterfaceReferenceTargetContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'NetworkInterfaceReferenceTargetContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 architecture: The operating system architecture.
    :attr bool dedicated_host_only: Images with this operating system can only be
          used on dedicated hosts or dedicated host groups.
    :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 href: The URL for this operating system.
    :attr str name: The globally unique name for this operating system.
    :attr str vendor: The vendor of the operating system.
    :attr str version: The major release version of this operating system.
    """

    def __init__(self, architecture: str, dedicated_host_only: bool,
                 display_name: str, family: str, href: str, name: str,
                 vendor: str, version: str) -> None:
        """
        Initialize a OperatingSystem object.

        :param str architecture: The operating system architecture.
        :param bool dedicated_host_only: Images with this operating system can only
               be used on dedicated hosts or dedicated host groups.
        :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 href: The URL for this operating system.
        :param str name: The globally unique name for this operating system.
        :param str vendor: The vendor of the operating system.
        :param str version: The major release version of this operating system.
        """
        self.architecture = architecture
        self.dedicated_host_only = dedicated_host_only
        self.display_name = display_name
        self.family = family
        self.href = href
        self.name = name
        self.vendor = vendor
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystem':
        """Initialize a OperatingSystem object from a json dictionary."""
        args = {}
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError(
                'Required property \'architecture\' not present in OperatingSystem JSON'
            )
        if 'dedicated_host_only' in _dict:
            args['dedicated_host_only'] = _dict.get('dedicated_host_only')
        else:
            raise ValueError(
                'Required property \'dedicated_host_only\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in OperatingSystem JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'architecture') and self.architecture is not None:
            _dict['architecture'] = self.architecture
        if hasattr(
                self,
                'dedicated_host_only') and self.dedicated_host_only is not None:
            _dict['dedicated_host_only'] = self.dedicated_host_only
        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, '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, '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 link 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 link to the next page of
          resources. This property is present 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 link 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 link to the next
               page of resources. This property is present 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a OperatingSystemCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a OperatingSystemCollectionNext object.

        :param str href: The URL for a 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 datetime created_at: The date and time that the public gateway was
          created.
    :attr str crn: The CRN for this public gateway.
    :attr PublicGatewayFloatingIp floating_ip: Reference to the floating IP which is
          bound to this public gateway.
    :attr str href: The URL for this public gateway.
    :attr str id: The unique identifier for this public gateway.
    :attr str name: The user-defined name for this public gateway.
    :attr ResourceGroupReference resource_group: The resource group for this public
          gateway.
    :attr str resource_type: The resource type.
    :attr str status: The status of the volume.
    :attr VPCReference vpc: The VPC this public gateway serves.
    :attr ZoneReference zone: The zone this public gateway resides in.
    """

    def __init__(self, created_at: datetime, crn: str,
                 floating_ip: 'PublicGatewayFloatingIp', href: str, id: str,
                 name: str, resource_group: 'ResourceGroupReference',
                 resource_type: str, status: str, vpc: 'VPCReference',
                 zone: 'ZoneReference') -> None:
        """
        Initialize a PublicGateway object.

        :param datetime created_at: The date and time that the public gateway was
               created.
        :param str crn: The CRN for this public gateway.
        :param PublicGatewayFloatingIp floating_ip: Reference to the floating IP
               which is bound to this public gateway.
        :param str href: The URL for this public gateway.
        :param str id: The unique identifier for this public gateway.
        :param str name: The user-defined name for this public gateway.
        :param ResourceGroupReference resource_group: The resource group for this
               public gateway.
        :param str resource_type: The resource type.
        :param str status: The status of the volume.
        :param VPCReference vpc: The VPC this public gateway serves.
        :param ZoneReference zone: The zone this public gateway resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.floating_ip = floating_ip
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        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 '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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGateway JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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_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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'floating_ip') and self.floating_ip is not None:
            _dict['floating_ip'] = self.floating_ip.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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 link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[PublicGateway] public_gateways: Collection of public gateways.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'PublicGatewayCollectionFirst',
                 limit: int,
                 public_gateways: List['PublicGateway'],
                 total_count: int,
                 *,
                 next: 'PublicGatewayCollectionNext' = None) -> None:
        """
        Initialize a PublicGatewayCollection object.

        :param PublicGatewayCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[PublicGateway] public_gateways: Collection of public gateways.
        :param int total_count: The total number of resources across all pages.
        :param PublicGatewayCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.public_gateways = public_gateways
        self.total_count = total_count

    @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 '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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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,
                   'public_gateways') and self.public_gateways is not None:
            _dict['public_gateways'] = [
                x.to_dict() for x in self.public_gateways
            ]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayCollectionNext object.

        :param str href: The URL for a 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 PublicGatewayFloatingIPPrototype():
    """
    PublicGatewayFloatingIPPrototype.

    """

    def __init__(self) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'PublicGatewayFloatingIPPrototypeFloatingIPIdentity',
                'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext'
            ]))
        raise Exception(msg)


class PublicGatewayFloatingIp():
    """
    Reference to the floating IP which is bound to this public gateway.

    :attr str address: The globally unique IP address.
    :attr str crn: The CRN for this floating IP.
    :attr FloatingIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this floating IP.
    :attr str id: The unique identifier for this floating IP.
    :attr str name: The unique user-defined name for this floating IP.
    """

    def __init__(self,
                 address: str,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'FloatingIPReferenceDeleted' = None) -> None:
        """
        Initialize a PublicGatewayFloatingIp object.

        :param str address: The globally unique IP address.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str id: The unique identifier for this floating IP.
        :param str name: The unique user-defined name for this floating IP.
        :param FloatingIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.address = address
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIp':
        """Initialize a PublicGatewayFloatingIp object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' 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 'deleted' in _dict:
            args['deleted'] = FloatingIPReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayFloatingIp JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 PublicGatewayPatch():
    """
    PublicGatewayPatch.

    :attr str name: (optional) The user-defined name for this public gateway. Names
          must be unique within the VPC the public gateway resides in.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a PublicGatewayPatch object.

        :param str name: (optional) The user-defined name for this public gateway.
               Names must be unique within the VPC the public gateway resides in.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayPatch':
        """Initialize a PublicGatewayPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPatch object from 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 PublicGatewayPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayReference():
    """
    PublicGatewayReference.

    :attr str crn: The CRN for this public gateway.
    :attr PublicGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this public gateway.
    :attr str id: The unique identifier 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,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'PublicGatewayReferenceDeleted' = None) -> None:
        """
        Initialize a PublicGatewayReference object.

        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str id: The unique identifier for this public gateway.
        :param str name: The user-defined name for this public gateway.
        :param str resource_type: The resource type.
        :param PublicGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGatewayReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = PublicGatewayReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 PublicGatewayReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a PublicGatewayReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayReferenceDeleted':
        """Initialize a PublicGatewayReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in PublicGatewayReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Region():
    """
    Region.

    :attr str endpoint: The API endpoint for this region.
    :attr str href: The URL for this region.
    :attr str name: The globally unique name for this region.
    :attr str status: The availability status of this region.
    """

    def __init__(self, endpoint: str, href: str, name: str,
                 status: str) -> None:
        """
        Initialize a Region object.

        :param str endpoint: The API endpoint for this region.
        :param str href: The URL for this region.
        :param str name: The globally unique name for this region.
        :param str status: The availability status of this region.
        """
        self.endpoint = endpoint
        self.href = href
        self.name = name
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Region':
        """Initialize a Region object from a json dictionary."""
        args = {}
        if 'endpoint' in _dict:
            args['endpoint'] = _dict.get('endpoint')
        else:
            raise ValueError(
                'Required property \'endpoint\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'endpoint') and self.endpoint is not None:
            _dict['endpoint'] = self.endpoint
        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, '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: Collection of regions.
    """

    def __init__(self, regions: List['Region']) -> None:
        """
        Initialize a RegionCollection object.

        :param List[Region] regions: Collection of regions.
        """
        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 href: The URL for this region.
    :attr str name: The globally unique name for this region.
    """

    def __init__(self, href: str, name: str) -> None:
        """
        Initialize a RegionReference object.

        :param str href: The URL for this region.
        :param str name: The globally unique name for this region.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionReference':
        """Initialize a RegionReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RegionReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, '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 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 ReservedIP():
    """
    ReservedIP.

    :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.
    :attr bool auto_delete: If set to `true`, this reserved IP will be automatically
          deleted when the target is deleted or when the reserved IP is unbound.
    :attr datetime created_at: The date and time that the reserved IP was created.
    :attr str href: The URL for this reserved IP.
    :attr str id: The unique identifier for this reserved IP.
    :attr str name: The user-defined or system-provided name for this reserved IP.
    :attr str owner: The owner of a reserved IP, defining whether it is managed by
          the user or the provider.
    :attr str resource_type: The resource type.
    :attr ReservedIPTarget target: (optional) The target of this reserved IP.
    """

    def __init__(self,
                 address: str,
                 auto_delete: bool,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 owner: str,
                 resource_type: str,
                 *,
                 target: 'ReservedIPTarget' = None) -> None:
        """
        Initialize a ReservedIP 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.
        :param bool auto_delete: If set to `true`, this reserved IP will be
               automatically deleted when the target is deleted or when the reserved IP is
               unbound.
        :param datetime created_at: The date and time that the reserved IP was
               created.
        :param str href: The URL for this reserved IP.
        :param str id: The unique identifier for this reserved IP.
        :param str name: The user-defined or system-provided name for this reserved
               IP.
        :param str owner: The owner of a reserved IP, defining whether it is
               managed by the user or the provider.
        :param str resource_type: The resource type.
        :param ReservedIPTarget target: (optional) The target of this reserved IP.
        """
        self.address = address
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.owner = owner
        self.resource_type = resource_type
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIP':
        """Initialize a ReservedIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in ReservedIP JSON')
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError(
                'Required property \'auto_delete\' not present in ReservedIP 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 ReservedIP JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ReservedIP JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ReservedIP JSON')
        if 'owner' in _dict:
            args['owner'] = _dict.get('owner')
        else:
            raise ValueError(
                'Required property \'owner\' not present in ReservedIP JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in ReservedIP JSON'
            )
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIP object from 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
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'owner') and self.owner is not None:
            _dict['owner'] = self.owner
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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 ReservedIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class OwnerEnum(str, Enum):
        """
        The owner of a reserved IP, defining whether it is managed by the user or the
        provider.
        """
        PROVIDER = 'provider'
        USER = 'user'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        SUBNET_RESERVED_IP = 'subnet_reserved_ip'


class ReservedIPCollection():
    """
    ReservedIPCollection.

    :attr ReservedIPCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ReservedIPCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[ReservedIP] reserved_ips: Collection of reserved IPs in this subnet.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'ReservedIPCollectionFirst',
                 limit: int,
                 reserved_ips: List['ReservedIP'],
                 total_count: int,
                 *,
                 next: 'ReservedIPCollectionNext' = None) -> None:
        """
        Initialize a ReservedIPCollection object.

        :param ReservedIPCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[ReservedIP] reserved_ips: Collection of reserved IPs in this
               subnet.
        :param int total_count: The total number of resources across all pages.
        :param ReservedIPCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.reserved_ips = reserved_ips
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollection':
        """Initialize a ReservedIPCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ReservedIPCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in ReservedIPCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in ReservedIPCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = ReservedIPCollectionNext.from_dict(_dict.get('next'))
        if 'reserved_ips' in _dict:
            args['reserved_ips'] = [
                ReservedIP.from_dict(x) for x in _dict.get('reserved_ips')
            ]
        else:
            raise ValueError(
                'Required property \'reserved_ips\' not present in ReservedIPCollection JSON'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in ReservedIPCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollection object from 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, 'reserved_ips') and self.reserved_ips is not None:
            _dict['reserved_ips'] = [x.to_dict() for x in self.reserved_ips]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 ReservedIPCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionEndpointGatewayContext():
    """
    ReservedIPCollectionEndpointGatewayContext.

    :attr ReservedIPCollectionEndpointGatewayContextFirst first: A link to the first
          page of resources.
    :attr List[ReservedIP] ips: Collection of reserved IPs bound to an endpoint
          gateway.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ReservedIPCollectionEndpointGatewayContextNext next: (optional) A link to
          the next page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
            self,
            first: 'ReservedIPCollectionEndpointGatewayContextFirst',
            ips: List['ReservedIP'],
            limit: int,
            total_count: int,
            *,
            next: 'ReservedIPCollectionEndpointGatewayContextNext' = None
    ) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContext object.

        :param ReservedIPCollectionEndpointGatewayContextFirst first: A link to the
               first page of resources.
        :param List[ReservedIP] ips: Collection of reserved IPs bound to an
               endpoint gateway.
        :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 ReservedIPCollectionEndpointGatewayContextNext next: (optional) A
               link to the next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.ips = ips
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'ReservedIPCollectionEndpointGatewayContext':
        """Initialize a ReservedIPCollectionEndpointGatewayContext object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args[
                'first'] = ReservedIPCollectionEndpointGatewayContextFirst.from_dict(
                    _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in ReservedIPCollectionEndpointGatewayContext JSON'
            )
        if 'ips' in _dict:
            args['ips'] = [ReservedIP.from_dict(x) for x in _dict.get('ips')]
        else:
            raise ValueError(
                'Required property \'ips\' not present in ReservedIPCollectionEndpointGatewayContext JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in ReservedIPCollectionEndpointGatewayContext JSON'
            )
        if 'next' in _dict:
            args[
                'next'] = ReservedIPCollectionEndpointGatewayContextNext.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 ReservedIPCollectionEndpointGatewayContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionEndpointGatewayContext object from 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, 'ips') and self.ips is not None:
            _dict['ips'] = [x.to_dict() for x in self.ips]
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollectionEndpointGatewayContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'ReservedIPCollectionEndpointGatewayContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'ReservedIPCollectionEndpointGatewayContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionEndpointGatewayContextFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContextFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'ReservedIPCollectionEndpointGatewayContextFirst':
        """Initialize a ReservedIPCollectionEndpointGatewayContextFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPCollectionEndpointGatewayContextFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionEndpointGatewayContextFirst object from 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 ReservedIPCollectionEndpointGatewayContextFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'ReservedIPCollectionEndpointGatewayContextFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'ReservedIPCollectionEndpointGatewayContextFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionEndpointGatewayContextNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContextNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'ReservedIPCollectionEndpointGatewayContextNext':
        """Initialize a ReservedIPCollectionEndpointGatewayContextNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPCollectionEndpointGatewayContextNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionEndpointGatewayContextNext object from 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 ReservedIPCollectionEndpointGatewayContextNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'ReservedIPCollectionEndpointGatewayContextNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'ReservedIPCollectionEndpointGatewayContextNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ReservedIPCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionFirst':
        """Initialize a ReservedIPCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionFirst object from 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 ReservedIPCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ReservedIPCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionNext':
        """Initialize a ReservedIPCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionNext object from 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 ReservedIPCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPPatch():
    """
    ReservedIPPatch.

    :attr bool auto_delete: (optional) If set to `true`, this reserved IP will be
          automatically deleted when the target is deleted or when the reserved IP is
          unbound. The value cannot be set to `true` if the reserved IP is unbound.
    :attr str name: (optional) The user-defined name for this reserved IP. Names
          must be unique within the subnet the reserved IP resides in. Names beginning
          with `ibm-` are reserved for provider-owned resources.
    """

    def __init__(self, *, auto_delete: bool = None, name: str = None) -> None:
        """
        Initialize a ReservedIPPatch object.

        :param bool auto_delete: (optional) If set to `true`, this reserved IP will
               be automatically deleted when the target is deleted or when the reserved IP
               is unbound. The value cannot be set to `true` if the reserved IP is
               unbound.
        :param str name: (optional) The user-defined name for this reserved IP.
               Names must be unique within the subnet the reserved IP resides in. Names
               beginning with `ibm-` are reserved for provider-owned resources.
        """
        self.auto_delete = auto_delete
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPPatch':
        """Initialize a ReservedIPPatch object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        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 ReservedIPPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPReference():
    """
    ReservedIPReference.

    :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.
    :attr ReservedIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this reserved IP.
    :attr str id: The unique identifier for this reserved IP.
    :attr str name: The user-defined or system-provided name for this reserved IP.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 address: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'ReservedIPReferenceDeleted' = None) -> None:
        """
        Initialize a ReservedIPReference 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.
        :param str href: The URL for this reserved IP.
        :param str id: The unique identifier for this reserved IP.
        :param str name: The user-defined or system-provided name for this reserved
               IP.
        :param str resource_type: The resource type.
        :param ReservedIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.address = address
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPReference':
        """Initialize a ReservedIPReference object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in ReservedIPReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = ReservedIPReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ReservedIPReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ReservedIPReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in ReservedIPReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPReference object from 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
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 ReservedIPReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        SUBNET_RESERVED_IP = 'subnet_reserved_ip'


class ReservedIPReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a ReservedIPReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPReferenceDeleted':
        """Initialize a ReservedIPReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in ReservedIPReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTarget():
    """
    The target of this reserved IP.

    """

    def __init__(self) -> None:
        """
        Initialize a ReservedIPTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ReservedIPTargetEndpointGatewayReference']))
        raise Exception(msg)


class ReservedIPTargetPrototype():
    """
    The target this reserved IP is to be bound to.

    """

    def __init__(self) -> None:
        """
        Initialize a ReservedIPTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ReservedIPTargetPrototypeEndpointGatewayIdentity']))
        raise Exception(msg)


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 href: The URL for this resource group.
    :attr str id: The unique identifier for this resource group.
    :attr str name: The user-defined name for this resource group.
    """

    def __init__(self, href: str, id: str, name: str) -> None:
        """
        Initialize a ResourceGroupReference object.

        :param str href: The URL for this resource group.
        :param str id: The unique identifier for this resource group.
        :param str name: The user-defined name for this resource group.
        """
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ResourceGroupReference':
        """Initialize a ResourceGroupReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ResourceGroupReference JSON'
            )
        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'
            )
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 datetime created_at: The date and time that the route was created.
    :attr str destination: The destination of the route.
    :attr str href: The URL for this route.
    :attr str id: The unique identifier for this route.
    :attr str lifecycle_state: The lifecycle state of the route.
    :attr str name: The user-defined name for this route.
    :attr RouteNextHop next_hop: If `action` is `deliver`, the next hop that packets
          will be delivered to.  For
          other `action` values, its `address` will be `0.0.0.0`.
    :attr ZoneReference zone: The zone the route applies to. (Traffic from subnets
          in this zone will be
          subject to this route.).
    """

    def __init__(self, created_at: datetime, destination: str, href: str,
                 id: str, lifecycle_state: str, name: str,
                 next_hop: 'RouteNextHop', zone: 'ZoneReference') -> None:
        """
        Initialize a Route object.

        :param datetime created_at: The date and time that the route was created.
        :param str destination: The destination of the route.
        :param str href: The URL for this route.
        :param str id: The unique identifier for this route.
        :param str lifecycle_state: The lifecycle state of the route.
        :param str name: The user-defined name for this route.
        :param RouteNextHop next_hop: If `action` is `deliver`, the next hop that
               packets will be delivered to.  For
               other `action` values, its `address` will be `0.0.0.0`.
        :param ZoneReference zone: The zone the route applies to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        """
        self.created_at = created_at
        self.destination = destination
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.next_hop = next_hop
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Route':
        """Initialize a Route object from a json dictionary."""
        args = {}
        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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' 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 'next_hop' in _dict:
            args['next_hop'] = _dict.get('next_hop')
        else:
            raise ValueError(
                'Required property \'next_hop\' 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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, '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 RouteCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr RouteCollectionNext next: (optional) A link to the next page of resources.
          This property is present for all pages
          except the last page.
    :attr List[Route] routes: Collection of routes.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'RouteCollectionFirst',
                 limit: int,
                 routes: List['Route'],
                 total_count: int,
                 *,
                 next: 'RouteCollectionNext' = None) -> None:
        """
        Initialize a RouteCollection object.

        :param RouteCollectionFirst first: A link to the first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[Route] routes: Collection of routes.
        :param int total_count: The total number of resources across all pages.
        :param RouteCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.routes = routes
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollection':
        """Initialize a RouteCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = RouteCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in RouteCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in RouteCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = RouteCollectionNext.from_dict(_dict.get('next'))
        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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, '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, 'routes') and self.routes is not None:
            _dict['routes'] = [x.to_dict() for x in self.routes]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 RouteCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a RouteCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionFirst':
        """Initialize a RouteCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RouteCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionFirst object from 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 RouteCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a RouteCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionNext':
        """Initialize a RouteCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RouteCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionNext object from 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 RouteCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionNext') -> 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',
                 'RouteNextHopVPNGatewayConnectionReference']))
        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',
                'RouteNextHopPrototypeVPNGatewayConnectionIdentity'
            ]))
        raise Exception(msg)


class RoutePatch():
    """
    RoutePatch.

    :attr str name: (optional) The user-defined name for this route. Names must be
          unique within the VPC routing table the route resides in.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a RoutePatch object.

        :param str name: (optional) The user-defined name for this route. Names
               must be unique within the VPC routing table the route resides in.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutePatch':
        """Initialize a RoutePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePatch object from 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 RoutePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutePrototype():
    """
    RoutePrototype.

    :attr str action: (optional) The action to perform with a packet matching the
          route:
          - `delegate`: delegate to the system's built-in routes
          - `delegate_vpc`: delegate to the system's built-in routes, ignoring
          Internet-bound
            routes
          - `deliver`: deliver the packet to the specified `next_hop`
          - `drop`: drop the packet.
    :attr str destination: The destination of the route. At most two routes per
          `zone` in a table can have the same destination, and only if both routes have an
          `action` of `deliver` and the
          `next_hop` is an IP address.
    :attr 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.
    :attr RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`, the
          next hop that packets will be delivered to.  For
          other `action` values, it must be omitted or specified as `0.0.0.0`.
    :attr ZoneIdentity zone: The zone to apply the route to. (Traffic from subnets
          in this zone will be
          subject to this route.).
    """

    def __init__(self,
                 destination: str,
                 zone: 'ZoneIdentity',
                 *,
                 action: str = None,
                 name: str = None,
                 next_hop: 'RouteNextHopPrototype' = None) -> None:
        """
        Initialize a RoutePrototype object.

        :param str destination: The destination of the route. At most two routes
               per `zone` in a table can have the same destination, and only if both
               routes have an `action` of `deliver` and the
               `next_hop` is an IP address.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str action: (optional) The action to perform with a packet matching
               the route:
               - `delegate`: delegate to the system's built-in routes
               - `delegate_vpc`: delegate to the system's built-in routes, ignoring
               Internet-bound
                 routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to.  For
               other `action` values, it must be omitted or specified as `0.0.0.0`.
        """
        self.action = action
        self.destination = destination
        self.name = name
        self.next_hop = next_hop
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutePrototype':
        """Initialize a RoutePrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError(
                'Required property \'destination\' not present in RoutePrototype JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'next_hop' in _dict:
            args['next_hop'] = _dict.get('next_hop')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in RoutePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePrototype object from 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, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, '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 RoutePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform with a packet matching the route:
        - `delegate`: delegate to the system's built-in routes
        - `delegate_vpc`: delegate to the system's built-in routes, ignoring
        Internet-bound
          routes
        - `deliver`: deliver the packet to the specified `next_hop`
        - `drop`: drop the packet.
        """
        DELEGATE = 'delegate'
        DELEGATE_VPC = 'delegate_vpc'
        DELIVER = 'deliver'
        DROP = 'drop'


class RouteReference():
    """
    RouteReference.

    :attr RouteReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this route.
    :attr str id: The unique identifier for this route.
    :attr str name: The user-defined name for this route.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'RouteReferenceDeleted' = None) -> None:
        """
        Initialize a RouteReference object.

        :param str href: The URL for this route.
        :param str id: The unique identifier for this route.
        :param str name: The user-defined name for this route.
        :param RouteReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReference':
        """Initialize a RouteReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = RouteReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RouteReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in RouteReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in RouteReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a RouteReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReferenceDeleted':
        """Initialize a RouteReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in RouteReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTable():
    """
    RoutingTable.

    :attr datetime created_at: The date and time that this routing table was
          created.
    :attr str href: The URL for this routing table.
    :attr str id: The unique identifier for this routing table.
    :attr bool is_default: Indicates whether this is the default routing table for
          this VPC.
    :attr str lifecycle_state: The lifecycle state of the routing table.
    :attr str name: The user-defined name for this routing table.
    :attr str resource_type: The resource type.
    :attr bool route_direct_link_ingress: Indicates whether this routing table is
          used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr bool route_transit_gateway_ingress: Indicates whether this routing table
          is used to route traffic that originates from from [Transit
          Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr bool route_vpc_zone_ingress: Indicates whether this routing table is used
          to route traffic that originates from subnets in other zones in this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr List[RouteReference] routes: The routes for this routing table.
    :attr List[SubnetReference] subnets: The subnets to which this routing table is
          attached.
    """

    def __init__(self, created_at: datetime, href: str, id: str,
                 is_default: bool, lifecycle_state: str, name: str,
                 resource_type: str, route_direct_link_ingress: bool,
                 route_transit_gateway_ingress: bool,
                 route_vpc_zone_ingress: bool, routes: List['RouteReference'],
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a RoutingTable object.

        :param datetime created_at: The date and time that this routing table was
               created.
        :param str href: The URL for this routing table.
        :param str id: The unique identifier for this routing table.
        :param bool is_default: Indicates whether this is the default routing table
               for this VPC.
        :param str lifecycle_state: The lifecycle state of the routing table.
        :param str name: The user-defined name for this routing table.
        :param str resource_type: The resource type.
        :param bool route_direct_link_ingress: Indicates whether this routing table
               is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param bool route_transit_gateway_ingress: Indicates whether this routing
               table is used to route traffic that originates from from [Transit
               Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param bool route_vpc_zone_ingress: Indicates whether this routing table is
               used to route traffic that originates from subnets in other zones in this
               VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param List[RouteReference] routes: The routes for this routing table.
        :param List[SubnetReference] subnets: The subnets to which this routing
               table is attached.
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.is_default = is_default
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type
        self.route_direct_link_ingress = route_direct_link_ingress
        self.route_transit_gateway_ingress = route_transit_gateway_ingress
        self.route_vpc_zone_ingress = route_vpc_zone_ingress
        self.routes = routes
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTable':
        """Initialize a RoutingTable object from a json dictionary."""
        args = {}
        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 RoutingTable JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RoutingTable JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in RoutingTable JSON')
        if 'is_default' in _dict:
            args['is_default'] = _dict.get('is_default')
        else:
            raise ValueError(
                'Required property \'is_default\' not present in RoutingTable JSON'
            )
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError(
                'Required property \'lifecycle_state\' not present in RoutingTable JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in RoutingTable JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in RoutingTable JSON'
            )
        if 'route_direct_link_ingress' in _dict:
            args['route_direct_link_ingress'] = _dict.get(
                'route_direct_link_ingress')
        else:
            raise ValueError(
                'Required property \'route_direct_link_ingress\' not present in RoutingTable JSON'
            )
        if 'route_transit_gateway_ingress' in _dict:
            args['route_transit_gateway_ingress'] = _dict.get(
                'route_transit_gateway_ingress')
        else:
            raise ValueError(
                'Required property \'route_transit_gateway_ingress\' not present in RoutingTable JSON'
            )
        if 'route_vpc_zone_ingress' in _dict:
            args['route_vpc_zone_ingress'] = _dict.get('route_vpc_zone_ingress')
        else:
            raise ValueError(
                'Required property \'route_vpc_zone_ingress\' not present in RoutingTable JSON'
            )
        if 'routes' in _dict:
            args['routes'] = [
                RouteReference.from_dict(x) for x in _dict.get('routes')
            ]
        else:
            raise ValueError(
                'Required property \'routes\' not present in RoutingTable 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 RoutingTable JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTable object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        if hasattr(self,
                   'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        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, 'route_direct_link_ingress'
                  ) and self.route_direct_link_ingress is not None:
            _dict['route_direct_link_ingress'] = self.route_direct_link_ingress
        if hasattr(self, 'route_transit_gateway_ingress'
                  ) and self.route_transit_gateway_ingress is not None:
            _dict[
                'route_transit_gateway_ingress'] = self.route_transit_gateway_ingress
        if hasattr(self, 'route_vpc_zone_ingress'
                  ) and self.route_vpc_zone_ingress is not None:
            _dict['route_vpc_zone_ingress'] = self.route_vpc_zone_ingress
        if hasattr(self, 'routes') and self.routes is not None:
            _dict['routes'] = [x.to_dict() for x in self.routes]
        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 RoutingTable object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTable') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTable') -> 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 routing table.
        """
        DELETED = 'deleted'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        UPDATING = 'updating'
        WAITING = 'waiting'
        SUSPENDED = 'suspended'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        ROUTING_TABLE = 'routing_table'


class RoutingTableCollection():
    """
    RoutingTableCollection.

    :attr RoutingTableCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr RoutingTableCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[RoutingTable] routing_tables: Collection of routing tables.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'RoutingTableCollectionFirst',
                 limit: int,
                 routing_tables: List['RoutingTable'],
                 total_count: int,
                 *,
                 next: 'RoutingTableCollectionNext' = None) -> None:
        """
        Initialize a RoutingTableCollection object.

        :param RoutingTableCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[RoutingTable] routing_tables: Collection of routing tables.
        :param int total_count: The total number of resources across all pages.
        :param RoutingTableCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.routing_tables = routing_tables
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableCollection':
        """Initialize a RoutingTableCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = RoutingTableCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in RoutingTableCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in RoutingTableCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = RoutingTableCollectionNext.from_dict(
                _dict.get('next'))
        if 'routing_tables' in _dict:
            args['routing_tables'] = [
                RoutingTable.from_dict(x) for x in _dict.get('routing_tables')
            ]
        else:
            raise ValueError(
                'Required property \'routing_tables\' not present in RoutingTableCollection JSON'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in RoutingTableCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableCollection object from 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, 'routing_tables') and self.routing_tables is not None:
            _dict['routing_tables'] = [x.to_dict() for x in self.routing_tables]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 RoutingTableCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a RoutingTableCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableCollectionFirst':
        """Initialize a RoutingTableCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RoutingTableCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableCollectionFirst object from 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 RoutingTableCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a RoutingTableCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableCollectionNext':
        """Initialize a RoutingTableCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RoutingTableCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableCollectionNext object from 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 RoutingTableCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableIdentity():
    """
    Identifies a routing table by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a RoutingTableIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(
                ['RoutingTableIdentityById', 'RoutingTableIdentityByHref']))
        raise Exception(msg)


class RoutingTablePatch():
    """
    RoutingTablePatch.

    :attr str name: (optional) The user-defined name for this routing table. Names
          must be unique within the VPC the routing table resides in.
    :attr bool route_direct_link_ingress: (optional) Indicates whether this routing
          table is used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC. Updating to `true`
          selects this routing table, provided no other routing table in the VPC already
          has this property set to `true`, and no subnets are attached to this routing
          table. Updating to `false` deselects this routing table.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    :attr bool route_transit_gateway_ingress: (optional) Indicates whether this
          routing table is used to route traffic that originates from
          [Transit Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this VPC.
          Updating to
          `true` selects this routing table, provided no other routing table in the VPC
          already has this property set to `true`, and no subnets are attached to this
          routing table. Updating to `false` deselects this routing table.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
          If [Classic
          Access](https://cloud.ibm.com/docs/vpc?topic=vpc-setting-up-access-to-classic-infrastructure)
          is enabled for this VPC, and this property is set to `true`, its incoming
          traffic will also be routed according to this routing table.
    :attr bool route_vpc_zone_ingress: (optional) Indicates whether this routing
          table is used to route traffic that originates from subnets in other zones in
          this VPC. Updating to `true` selects this routing table, provided no other
          routing table in the VPC already has this property set to `true`, and no subnets
          are attached to this routing table. Updating to `false` deselects this routing
          table.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address within the VPC's address prefix ranges. Therefore,
          if an incoming packet matches a route with a `next_hop` of an internet-bound IP
          address or a VPN gateway connection, the packet will be dropped.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 route_direct_link_ingress: bool = None,
                 route_transit_gateway_ingress: bool = None,
                 route_vpc_zone_ingress: bool = None) -> None:
        """
        Initialize a RoutingTablePatch object.

        :param str name: (optional) The user-defined name for this routing table.
               Names must be unique within the VPC the routing table resides in.
        :param bool route_direct_link_ingress: (optional) Indicates whether this
               routing table is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC. Updating to
               `true` selects this routing table, provided no other routing table in the
               VPC already has this property set to `true`, and no subnets are attached to
               this routing table. Updating to `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        :param bool route_transit_gateway_ingress: (optional) Indicates whether
               this routing table is used to route traffic that originates from
               [Transit Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this
               VPC. Updating to
               `true` selects this routing table, provided no other routing table in the
               VPC already has this property set to `true`, and no subnets are attached to
               this routing table. Updating to `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
               If [Classic
               Access](https://cloud.ibm.com/docs/vpc?topic=vpc-setting-up-access-to-classic-infrastructure)
               is enabled for this VPC, and this property is set to `true`, its incoming
               traffic will also be routed according to this routing table.
        :param bool route_vpc_zone_ingress: (optional) Indicates whether this
               routing table is used to route traffic that originates from subnets in
               other zones in this VPC. Updating to `true` selects this routing table,
               provided no other routing table in the VPC already has this property set to
               `true`, and no subnets are attached to this routing table. Updating to
               `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address within the VPC's address prefix
               ranges. Therefore, if an incoming packet matches a route with a `next_hop`
               of an internet-bound IP address or a VPN gateway connection, the packet
               will be dropped.
        """
        self.name = name
        self.route_direct_link_ingress = route_direct_link_ingress
        self.route_transit_gateway_ingress = route_transit_gateway_ingress
        self.route_vpc_zone_ingress = route_vpc_zone_ingress

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTablePatch':
        """Initialize a RoutingTablePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'route_direct_link_ingress' in _dict:
            args['route_direct_link_ingress'] = _dict.get(
                'route_direct_link_ingress')
        if 'route_transit_gateway_ingress' in _dict:
            args['route_transit_gateway_ingress'] = _dict.get(
                'route_transit_gateway_ingress')
        if 'route_vpc_zone_ingress' in _dict:
            args['route_vpc_zone_ingress'] = _dict.get('route_vpc_zone_ingress')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTablePatch object from 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, 'route_direct_link_ingress'
                  ) and self.route_direct_link_ingress is not None:
            _dict['route_direct_link_ingress'] = self.route_direct_link_ingress
        if hasattr(self, 'route_transit_gateway_ingress'
                  ) and self.route_transit_gateway_ingress is not None:
            _dict[
                'route_transit_gateway_ingress'] = self.route_transit_gateway_ingress
        if hasattr(self, 'route_vpc_zone_ingress'
                  ) and self.route_vpc_zone_ingress is not None:
            _dict['route_vpc_zone_ingress'] = self.route_vpc_zone_ingress
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTablePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTablePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTablePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableReference():
    """
    RoutingTableReference.

    :attr RoutingTableReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this routing table.
    :attr str id: The unique identifier for this routing table.
    :attr str name: The user-defined name for this routing table.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'RoutingTableReferenceDeleted' = None) -> None:
        """
        Initialize a RoutingTableReference object.

        :param str href: The URL for this routing table.
        :param str id: The unique identifier for this routing table.
        :param str name: The user-defined name for this routing table.
        :param str resource_type: The resource type.
        :param RoutingTableReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableReference':
        """Initialize a RoutingTableReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = RoutingTableReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RoutingTableReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in RoutingTableReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in RoutingTableReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in RoutingTableReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 RoutingTableReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        ROUTING_TABLE = 'routing_table'


class RoutingTableReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a RoutingTableReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableReferenceDeleted':
        """Initialize a RoutingTableReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in RoutingTableReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroup():
    """
    SecurityGroup.

    :attr datetime created_at: The date and time that this security group was
          created.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :attr str name: The user-defined name for this security group. Names must be
          unique within the VPC the security group resides in.
    :attr List[NetworkInterfaceReference] network_interfaces: Array of references to
          network interfaces.
    :attr ResourceGroupReference resource_group: The resource group for this
          security group.
    :attr List[SecurityGroupRule] rules: Array of rules for this security group. If
          no rules exist, all traffic will be denied.
    :attr List[SecurityGroupTargetReference] targets: Array of references to
          targets.
    :attr VPCReference vpc: The VPC this security group is a part of.
    """

    def __init__(self, created_at: datetime, crn: str, href: str, id: str,
                 name: str,
                 network_interfaces: List['NetworkInterfaceReference'],
                 resource_group: 'ResourceGroupReference',
                 rules: List['SecurityGroupRule'],
                 targets: List['SecurityGroupTargetReference'],
                 vpc: 'VPCReference') -> None:
        """
        Initialize a SecurityGroup object.

        :param datetime created_at: The date and time that this security group was
               created.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :param str name: The user-defined name for this security group. Names must
               be unique within the VPC the security group resides in.
        :param List[NetworkInterfaceReference] network_interfaces: Array of
               references to network interfaces.
        :param ResourceGroupReference resource_group: The resource group for this
               security group.
        :param List[SecurityGroupRule] rules: Array of rules for this security
               group. If no rules exist, all traffic will be denied.
        :param List[SecurityGroupTargetReference] targets: Array of references to
               targets.
        :param VPCReference vpc: The VPC this security group is a part of.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.network_interfaces = network_interfaces
        self.resource_group = resource_group
        self.rules = rules
        self.targets = targets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroup':
        """Initialize a SecurityGroup object from a json dictionary."""
        args = {}
        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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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 '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 '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 'targets' in _dict:
            args['targets'] = _dict.get('targets')
        else:
            raise ValueError(
                'Required property \'targets\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, '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,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            _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]
        if hasattr(self, 'targets') and self.targets is not None:
            targets_list = []
            for x in self.targets:
                if isinstance(x, dict):
                    targets_list.append(x)
                else:
                    targets_list.append(x.to_dict())
            _dict['targets'] = targets_list
        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 link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[SecurityGroup] security_groups: Collection of security groups.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'SecurityGroupCollectionFirst',
                 limit: int,
                 security_groups: List['SecurityGroup'],
                 total_count: int,
                 *,
                 next: 'SecurityGroupCollectionNext' = None) -> None:
        """
        Initialize a SecurityGroupCollection object.

        :param SecurityGroupCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[SecurityGroup] security_groups: Collection of security groups.
        :param int total_count: The total number of resources across all pages.
        :param SecurityGroupCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.security_groups = security_groups
        self.total_count = total_count

    @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 '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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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,
                   'security_groups') and self.security_groups is not None:
            _dict['security_groups'] = [
                x.to_dict() for x in self.security_groups
            ]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupCollectionNext object.

        :param str href: The URL for a 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 SecurityGroupPatch():
    """
    SecurityGroupPatch.

    :attr str name: (optional) The user-defined name for this security group. Names
          must be unique within the VPC the security group resides in.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a SecurityGroupPatch object.

        :param str name: (optional) The user-defined name for this security group.
               Names must be unique within the VPC the security group resides in.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupPatch':
        """Initialize a SecurityGroupPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupPatch object from 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 SecurityGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupReference():
    """
    SecurityGroupReference.

    :attr str crn: The security group's CRN.
    :attr SecurityGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :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,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'SecurityGroupReferenceDeleted' = None) -> None:
        """
        Initialize a SecurityGroupReference object.

        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :param str name: The user-defined name for this security group. Names must
               be unique within the VPC the security group resides in.
        :param SecurityGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupReference':
        """Initialize a SecurityGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = SecurityGroupReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 SecurityGroupReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a SecurityGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupReferenceDeleted':
        """Initialize a SecurityGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in SecurityGroupReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRule():
    """
    SecurityGroupRule.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :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,
                 direction: str,
                 href: str,
                 id: str,
                 remote: 'SecurityGroupRuleRemote',
                 *,
                 ip_version: str = None,
                 protocol: str = None) -> None:
        """
        Initialize a SecurityGroupRule object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :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 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 SecurityGroupRulePatch():
    """
    SecurityGroupRulePatch.

    :attr int code: (optional) The ICMP traffic code to allow. Specify `null` to
          remove an existing ICMP traffic code value.
    :attr str direction: (optional) 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 int port_max: (optional) The inclusive upper bound of the protocol port
          range. Specify `null` to clear an existing upper bound. If a lower bound has
          been set, the upper bound must also be set, and must not be smaller.
    :attr int port_min: (optional) The inclusive lower bound of the protocol port
          range. Specify `null` to clear an existing lower bound. If an upper bound has
          been set, the lower bound must also be set, and must not be larger.
    :attr SecurityGroupRuleRemotePatch 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).
    :attr int type: (optional) The ICMP traffic type to allow. Specify `null` to
          remove an existing ICMP traffic type value.
    """

    def __init__(self,
                 *,
                 code: int = None,
                 direction: str = None,
                 ip_version: str = None,
                 port_max: int = None,
                 port_min: int = None,
                 remote: 'SecurityGroupRuleRemotePatch' = None,
                 type: int = None) -> None:
        """
        Initialize a SecurityGroupRulePatch object.

        :param int code: (optional) The ICMP traffic code to allow. Specify `null`
               to remove an existing ICMP traffic code value.
        :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 port_max: (optional) The inclusive upper bound of the protocol
               port range. Specify `null` to clear an existing upper bound. If a lower
               bound has been set, the upper bound must also be set, and must not be
               smaller.
        :param int port_min: (optional) The inclusive lower bound of the protocol
               port range. Specify `null` to clear an existing lower bound. If an upper
               bound has been set, the lower bound must also be set, and must not be
               larger.
        :param SecurityGroupRuleRemotePatch 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 int type: (optional) The ICMP traffic type to allow. Specify `null`
               to remove an existing ICMP traffic type value.
        """
        self.code = code
        self.direction = direction
        self.ip_version = ip_version
        self.port_max = port_max
        self.port_min = port_min
        self.remote = remote
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePatch':
        """Initialize a SecurityGroupRulePatch object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'port_max' in _dict:
            args['port_max'] = _dict.get('port_max')
        if 'port_min' in _dict:
            args['port_min'] = _dict.get('port_min')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        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, '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
        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, '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 SecurityGroupRulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePatch') -> 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 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 SecurityGroupRuleRemotePrototype 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: 'SecurityGroupRuleRemotePrototype' = 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 SecurityGroupRuleRemotePrototype 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 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 SecurityGroupRuleRemotePatch():
    """
    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 SecurityGroupRuleRemotePatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRuleRemotePatchIP',
                'SecurityGroupRuleRemotePatchCIDR',
                'SecurityGroupRuleRemotePatchSecurityGroupIdentity'
            ]))
        raise Exception(msg)


class SecurityGroupRuleRemotePrototype():
    """
    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 SecurityGroupRuleRemotePrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRuleRemotePrototypeIP',
                'SecurityGroupRuleRemotePrototypeCIDR',
                'SecurityGroupRuleRemotePrototypeSecurityGroupIdentity'
            ]))
        raise Exception(msg)


class SecurityGroupTargetCollection():
    """
    SecurityGroupTargetCollection.

    :attr SecurityGroupTargetCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr SecurityGroupTargetCollectionNext next: (optional) A link to the next page
          of resources. This property is present for all pages
          except the last page.
    :attr List[SecurityGroupTargetReference] targets: Collection of security group
          target references.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'SecurityGroupTargetCollectionFirst',
                 limit: int,
                 targets: List['SecurityGroupTargetReference'],
                 total_count: int,
                 *,
                 next: 'SecurityGroupTargetCollectionNext' = None) -> None:
        """
        Initialize a SecurityGroupTargetCollection object.

        :param SecurityGroupTargetCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[SecurityGroupTargetReference] targets: Collection of security
               group target references.
        :param int total_count: The total number of resources across all pages.
        :param SecurityGroupTargetCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.targets = targets
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetCollection':
        """Initialize a SecurityGroupTargetCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SecurityGroupTargetCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in SecurityGroupTargetCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in SecurityGroupTargetCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = SecurityGroupTargetCollectionNext.from_dict(
                _dict.get('next'))
        if 'targets' in _dict:
            args['targets'] = _dict.get('targets')
        else:
            raise ValueError(
                'Required property \'targets\' not present in SecurityGroupTargetCollection JSON'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' not present in SecurityGroupTargetCollection JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetCollection object from 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, 'targets') and self.targets is not None:
            targets_list = []
            for x in self.targets:
                if isinstance(x, dict):
                    targets_list.append(x)
                else:
                    targets_list.append(x.to_dict())
            _dict['targets'] = targets_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 SecurityGroupTargetCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetCollectionFirst():
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupTargetCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetCollectionFirst':
        """Initialize a SecurityGroupTargetCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupTargetCollectionFirst JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetCollectionFirst object from 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 SecurityGroupTargetCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetCollectionNext():
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupTargetCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetCollectionNext':
        """Initialize a SecurityGroupTargetCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupTargetCollectionNext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetCollectionNext object from 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 SecurityGroupTargetCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetReference():
    """
    The resource types that can be security group targets are expected to expand in the
    future. When iterating over security group targets, do not assume that every target
    resource will be from a known set of resource types. Optionally halt processing and
    surface an error, or bypass resources of unrecognized types.

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupTargetReference object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext',
                'SecurityGroupTargetReferenceLoadBalancerReference'
            ]))
        raise Exception(msg)


class Subnet():
    """
    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 datetime created_at: The date and time that the subnet was created.
    :attr str crn: The CRN for this subnet.
    :attr str href: The URL for this subnet.
    :attr str id: The unique identifier for this subnet.
    :attr str ip_version: The IP version(s) supported by this subnet.
    :attr str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
          format.
    :attr str name: The user-defined name for this subnet.
    :attr NetworkACLReference network_acl: The network ACL for this subnet.
    :attr PublicGatewayReference public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr ResourceGroupReference resource_group: The resource group for this subnet.
    :attr RoutingTableReference routing_table: The routing table for this subnet.
    :attr str status: The status of the 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 VPCReference vpc: The VPC this subnet is a part of.
    :attr ZoneReference zone: The zone this subnet resides in.
    """

    def __init__(self,
                 available_ipv4_address_count: int,
                 created_at: datetime,
                 crn: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 ipv4_cidr_block: str,
                 name: str,
                 network_acl: 'NetworkACLReference',
                 resource_group: 'ResourceGroupReference',
                 routing_table: 'RoutingTableReference',
                 status: str,
                 total_ipv4_address_count: int,
                 vpc: 'VPCReference',
                 zone: 'ZoneReference',
                 *,
                 public_gateway: 'PublicGatewayReference' = None) -> None:
        """
        Initialize a Subnet object.

        :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 datetime created_at: The date and time that the subnet was created.
        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str id: The unique identifier for this subnet.
        :param str ip_version: The IP version(s) supported by this subnet.
        :param str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
               format.
        :param str name: The user-defined name for this subnet.
        :param NetworkACLReference network_acl: The network ACL for this subnet.
        :param ResourceGroupReference resource_group: The resource group for this
               subnet.
        :param RoutingTableReference routing_table: The routing table for this
               subnet.
        :param str status: The status of the 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 VPCReference vpc: The VPC this subnet is a part of.
        :param ZoneReference zone: The zone this subnet resides in.
        :param PublicGatewayReference public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        """
        self.available_ipv4_address_count = available_ipv4_address_count
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.ipv4_cidr_block = ipv4_cidr_block
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.resource_group = resource_group
        self.routing_table = routing_table
        self.status = status
        self.total_ipv4_address_count = total_ipv4_address_count
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Subnet':
        """Initialize a Subnet object from a json dictionary."""
        args = {}
        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 '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 '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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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')
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 'public_gateway' in _dict:
            args['public_gateway'] = PublicGatewayReference.from_dict(
                _dict.get('public_gateway'))
        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 'routing_table' in _dict:
            args['routing_table'] = RoutingTableReference.from_dict(
                _dict.get('routing_table'))
        else:
            raise ValueError(
                'Required property \'routing_table\' not present in Subnet JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' 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 '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')
        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, '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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            _dict['public_gateway'] = self.public_gateway.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, 'routing_table') and self.routing_table is not None:
            _dict['routing_table'] = self.routing_table.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        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, '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 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 IpVersionEnum(str, Enum):
        """
        The IP version(s) supported by this subnet.
        """
        IPV4 = 'ipv4'

    class StatusEnum(str, Enum):
        """
        The status of the subnet.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


class SubnetCollection():
    """
    SubnetCollection.

    :attr SubnetCollectionFirst first: A link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[Subnet] subnets: Collection of subnets.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'SubnetCollectionFirst',
                 limit: int,
                 subnets: List['Subnet'],
                 total_count: int,
                 *,
                 next: 'SubnetCollectionNext' = None) -> None:
        """
        Initialize a SubnetCollection object.

        :param SubnetCollectionFirst first: A link to the first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[Subnet] subnets: Collection of subnets.
        :param int total_count: The total number of resources across all pages.
        :param SubnetCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.subnets = subnets
        self.total_count = total_count

    @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 '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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, 'subnets') and self.subnets is not None:
            _dict['subnets'] = [x.to_dict() for x in self.subnets]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SubnetCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SubnetCollectionNext object.

        :param str href: The URL for a 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 SubnetPatch():
    """
    SubnetPatch.

    :attr str name: (optional) The user-defined name for this subnet. Names must be
          unique within the VPC the subnet resides in.
    :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 RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet.  The routing table properties
          `route_direct_link_ingress`, `route_transit_gateway_ingress`, and
          `route_vpc_zone_ingress` must be `false`.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 routing_table: 'RoutingTableIdentity' = None) -> None:
        """
        Initialize a SubnetPatch object.

        :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 RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet.  The routing table properties
               `route_direct_link_ingress`, `route_transit_gateway_ingress`, and
               `route_vpc_zone_ingress` must be `false`.
        """
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.routing_table = routing_table

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetPatch':
        """Initialize a SubnetPatch 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 'routing_table' in _dict:
            args['routing_table'] = _dict.get('routing_table')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPatch object from 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, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.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 SubnetPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetPrototype():
    """
    SubnetPrototype.

    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :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 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 RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet. If unspecified, the default routing table
          for the VPC is used. The routing table properties `route_direct_link_ingress`,
          `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be `false`.
    :attr VPCIdentity vpc: The VPC the subnet is to be a part of.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 *,
                 ip_version: str = None,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 routing_table: 'RoutingTableIdentity' = None) -> None:
        """
        Initialize a SubnetPrototype object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :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 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 RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet. If unspecified, the default routing table
               for the VPC is used. The routing table properties
               `route_direct_link_ingress`,
               `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be
               `false`.
        """
        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 crn: The CRN for this subnet.
    :attr SubnetReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this subnet.
    :attr str id: The unique identifier for this subnet.
    :attr str name: The user-defined name for this subnet.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'SubnetReferenceDeleted' = None) -> None:
        """
        Initialize a SubnetReference object.

        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str id: The unique identifier for this subnet.
        :param str name: The user-defined name for this subnet.
        :param SubnetReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetReference':
        """Initialize a SubnetReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SubnetReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = SubnetReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SubnetReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 SubnetReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a SubnetReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetReferenceDeleted':
        """Initialize a SubnetReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in SubnetReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VCPU():
    """
    The 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 VCPU 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) -> 'VCPU':
        """Initialize a VCPU object from a json dictionary."""
        args = {}
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError(
                'Required property \'architecture\' not present in VCPU JSON')
        if 'count' in _dict:
            args['count'] = _dict.get('count')
        else:
            raise ValueError(
                'Required property \'count\' not present in VCPU JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VCPU object from 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 VCPU object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VCPU') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VCPU') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPC():
    """
    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 datetime created_at: The date and time that the VPC was created.
    :attr str crn: The CRN for this VPC.
    :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 NetworkACLReference default_network_acl: The default network ACL to use
          for subnets created in this VPC.
    :attr RoutingTableReference default_routing_table: The default routing table to
          use for subnets created in this VPC.
    :attr SecurityGroupReference default_security_group: The default security group
          to use for network interfaces created in this VPC.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The unique user-defined name for this VPC.
    :attr ResourceGroupReference resource_group: The resource group for this VPC.
    :attr str status: The status of this VPC.
    """

    def __init__(self,
                 classic_access: bool,
                 created_at: datetime,
                 crn: str,
                 default_network_acl: 'NetworkACLReference',
                 default_routing_table: 'RoutingTableReference',
                 default_security_group: 'SecurityGroupReference',
                 href: str,
                 id: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 status: str,
                 *,
                 cse_source_ips: List['VPCCSESourceIP'] = None) -> None:
        """
        Initialize a VPC object.

        :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 datetime created_at: The date and time that the VPC was created.
        :param str crn: The CRN for this VPC.
        :param NetworkACLReference default_network_acl: The default network ACL to
               use for subnets created in this VPC.
        :param RoutingTableReference default_routing_table: The default routing
               table to use for subnets created in this VPC.
        :param SecurityGroupReference default_security_group: The default security
               group to use for network interfaces created in this VPC.
        :param str href: The URL for this VPC.
        :param str id: The unique identifier for this VPC.
        :param str name: The unique user-defined name for this VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               VPC.
        :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.classic_access = classic_access
        self.created_at = created_at
        self.crn = crn
        self.cse_source_ips = cse_source_ips
        self.default_network_acl = default_network_acl
        self.default_routing_table = default_routing_table
        self.default_security_group = default_security_group
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPC':
        """Initialize a VPC object from a json dictionary."""
        args = {}
        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 '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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 '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 'default_routing_table' in _dict:
            args['default_routing_table'] = RoutingTableReference.from_dict(
                _dict.get('default_routing_table'))
        else:
            raise ValueError(
                'Required property \'default_routing_table\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPC JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' 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 '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 '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, 'classic_access') and self.classic_access is not None:
            _dict['classic_access'] = self.classic_access
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        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,
                'default_network_acl') and self.default_network_acl is not None:
            _dict['default_network_acl'] = self.default_network_acl.to_dict()
        if hasattr(self, 'default_routing_table'
                  ) and self.default_routing_table is not None:
            _dict['default_routing_table'] = self.default_routing_table.to_dict(
            )
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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
        return _dict

    def _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 resides
          in.
    """

    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
               resides in.
        """
        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 link 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 link to the next page of resources.
          This property is present 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 link 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 link to the next page of
               resources. This property is present 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPCCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPCCollectionNext object.

        :param str href: The URL for a 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 VPCPatch():
    """
    VPCPatch.

    :attr str name: (optional) The unique user-defined name for this VPC.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a VPCPatch object.

        :param str name: (optional) The unique user-defined name for this VPC.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCPatch':
        """Initialize a VPCPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCPatch object from 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 VPCPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCReference():
    """
    VPCReference.

    :attr str crn: The CRN for this VPC.
    :attr VPCReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The unique user-defined name for this VPC.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'VPCReferenceDeleted' = None) -> None:
        """
        Initialize a VPCReference object.

        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str id: The unique identifier for this VPC.
        :param str name: The unique user-defined name for this VPC.
        :param VPCReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReference':
        """Initialize a VPCReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPCReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPCReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPCReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 VPCReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a VPCReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReferenceDeleted':
        """Initialize a VPCReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in VPCReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGateway():
    """
    VPNGateway.

    :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 crn: The VPN gateway's CRN.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr List[VPNGatewayMember] members: Collection of VPN gateway members.
    :attr str name: The user-defined name for this VPN gateway.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr str resource_type: The resource type.
    :attr str status: The status of the VPN gateway.
    :attr SubnetReference subnet:
    """

    def __init__(self, connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, crn: str, href: str, id: str,
                 members: List['VPNGatewayMember'], name: str,
                 resource_group: 'ResourceGroupReference', resource_type: str,
                 status: str, subnet: 'SubnetReference') -> None:
        """
        Initialize a VPNGateway object.

        :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 crn: The VPN gateway's CRN.
        :param str href: The VPN gateway's canonical URL.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayMember] members: Collection of VPN gateway members.
        :param str name: The user-defined name for this VPN gateway.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param str resource_type: The resource type.
        :param str status: The status of the VPN gateway.
        :param SubnetReference subnet:
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayRouteMode', 'VPNGatewayPolicyMode']))
        raise Exception(msg)

    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 link 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 link to the next page of
          resources. This property is present 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 link 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 link to the next page of
               resources. This property is present 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'] = _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:
            vpn_gateways_list = []
            for x in self.vpn_gateways:
                if isinstance(x, dict):
                    vpn_gateways_list.append(x)
                else:
                    vpn_gateways_list.append(x.to_dict())
            _dict['vpn_gateways'] = vpn_gateways_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPNGatewayCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VPNGatewayCollectionNext object.

        :param str href: The URL for a 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 bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :attr str authentication_mode: The authentication mode. Only `psk` is currently
          supported.
    :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 str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :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.
    :attr str mode: The mode of the VPN gateway.
    :attr str name: The user-defined name for this VPN gateway connection.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The preshared key.
    :attr str resource_type: The resource type.
    :attr str status: The status of a VPN gateway connection.
    """

    def __init__(self,
                 admin_state_up: bool,
                 authentication_mode: str,
                 created_at: datetime,
                 dead_peer_detection: 'VPNGatewayConnectionDPD',
                 href: str,
                 id: str,
                 mode: str,
                 name: str,
                 peer_address: str,
                 psk: str,
                 resource_type: str,
                 status: str,
                 *,
                 ike_policy: 'IKEPolicyReference' = None,
                 ipsec_policy: 'IPsecPolicyReference' = None) -> None:
        """
        Initialize a VPNGatewayConnection object.

        :param bool admin_state_up: If set to false, the VPN gateway connection is
               shut down.
        :param str authentication_mode: The authentication mode. Only `psk` is
               currently supported.
        :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 str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
        :param str name: The user-defined name for this VPN gateway connection.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The preshared key.
        :param str resource_type: The resource type.
        :param str status: The status of a VPN gateway connection.
        :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.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VPNGatewayConnectionStaticRouteMode',
                'VPNGatewayConnectionPolicyMode'
            ]))
        raise Exception(msg)

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode. Only `psk` is currently supported.
        """
        PSK = 'psk'

    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        """
        POLICY = 'policy'
        ROUTE = 'route'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'

    class StatusEnum(str, Enum):
        """
        The status of a VPN gateway 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'] = _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:
            connections_list = []
            for x in self.connections:
                if isinstance(x, dict):
                    connections_list.append(x)
                else:
                    connections_list.append(x.to_dict())
            _dict['connections'] = connections_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 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 VPNGatewayConnectionPatch():
    """
    VPNGatewayConnectionPatch.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional) The Dead
          Peer Detection settings.
    :attr IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
          configuration. The absence of a policy indicates
          autonegotiation.
    :attr str name: (optional) The user-defined name for this VPN gateway
          connection.
    :attr str peer_address: (optional) The IP address of the peer VPN gateway.
    :attr str psk: (optional) The preshared key.
    """

    def __init__(self,
                 *,
                 admin_state_up: bool = None,
                 dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
                 ike_policy: 'IKEPolicyIdentity' = None,
                 ipsec_policy: 'IPsecPolicyIdentity' = None,
                 name: str = None,
                 peer_address: str = None,
                 psk: str = None) -> None:
        """
        Initialize a VPNGatewayConnectionPatch object.

        :param bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :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 str name: (optional) The user-defined name for this VPN gateway
               connection.
        :param str peer_address: (optional) The IP address of the peer VPN gateway.
        :param str psk: (optional) The preshared key.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch'
            ]))
        raise Exception(msg)


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 VPNGatewayConnectionPrototype():
    """
    VPNGatewayConnectionPrototype.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional) The Dead
          Peer Detection settings.
    :attr IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
          configuration. The absence of a policy indicates
          autonegotiation.
    :attr str name: (optional) The user-defined name for this VPN gateway
          connection.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The preshared key.
    """

    def __init__(self,
                 peer_address: str,
                 psk: str,
                 *,
                 admin_state_up: bool = None,
                 dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
                 ike_policy: 'IKEPolicyIdentity' = None,
                 ipsec_policy: 'IPsecPolicyIdentity' = None,
                 name: str = None) -> None:
        """
        Initialize a VPNGatewayConnectionPrototype object.

        :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 gateway
               connection is shut down.
        :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 str name: (optional) The user-defined name for this VPN gateway
               connection.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype',
                'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype'
            ]))
        raise Exception(msg)


class VPNGatewayConnectionReference():
    """
    VPNGatewayConnectionReference.

    :attr VPNGatewayConnectionReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :attr str name: The user-defined name for this VPN connection.
    :attr str resource_type: The resource type.
    """

    def __init__(
            self,
            href: str,
            id: str,
            name: str,
            resource_type: str,
            *,
            deleted: 'VPNGatewayConnectionReferenceDeleted' = None) -> None:
        """
        Initialize a VPNGatewayConnectionReference object.

        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str name: The user-defined name for this VPN connection.
        :param str resource_type: The resource type.
        :param VPNGatewayConnectionReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        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 'deleted' in _dict:
            args['deleted'] = VPNGatewayConnectionReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayConnectionReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 VPNGatewayConnectionReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a VPNGatewayConnectionReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionReferenceDeleted':
        """Initialize a VPNGatewayConnectionReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in VPNGatewayConnectionReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionStaticRouteModeTunnel():
    """
    VPNGatewayConnectionStaticRouteModeTunnel.

    :attr IP public_ip: The IP address of the VPN gateway member in which the tunnel
          resides.
    :attr str status: The status of the VPN Tunnel.
    """

    def __init__(self, public_ip: 'IP', status: str) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModeTunnel object.

        :param IP public_ip: The IP address of the VPN gateway member in which the
               tunnel resides.
        :param str status: The status of the VPN Tunnel.
        """
        self.public_ip = public_ip
        self.status = status

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'VPNGatewayConnectionStaticRouteModeTunnel':
        """Initialize a VPNGatewayConnectionStaticRouteModeTunnel object from a json dictionary."""
        args = {}
        if 'public_ip' in _dict:
            args['public_ip'] = IP.from_dict(_dict.get('public_ip'))
        else:
            raise ValueError(
                'Required property \'public_ip\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteModeTunnel object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'public_ip') and self.public_ip is not None:
            _dict['public_ip'] = self.public_ip.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 VPNGatewayConnectionStaticRouteModeTunnel object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'VPNGatewayConnectionStaticRouteModeTunnel') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'VPNGatewayConnectionStaticRouteModeTunnel') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the VPN Tunnel.
        """
        UP = 'up'
        DOWN = 'down'


class VPNGatewayMember():
    """
    VPNGatewayMember.

    :attr IP private_ip: (optional) The private IP address assigned to the VPN
          gateway member. This
          property will be present only when the VPN gateway status is
          `available`.
    :attr IP public_ip: The public IP address assigned to the VPN gateway member.
    :attr str role: The high availability role assigned to the VPN gateway member.
    :attr str status: The status of the VPN gateway member.
    """

    def __init__(self,
                 public_ip: 'IP',
                 role: str,
                 status: str,
                 *,
                 private_ip: 'IP' = None) -> None:
        """
        Initialize a VPNGatewayMember object.

        :param IP public_ip: The public IP address assigned to the VPN gateway
               member.
        :param str role: The high availability role assigned to the VPN gateway
               member.
        :param str status: The status of the VPN gateway member.
        :param IP private_ip: (optional) The private IP address assigned to the VPN
               gateway member. This
               property will be present only when the VPN gateway status is
               `available`.
        """
        self.private_ip = private_ip
        self.public_ip = public_ip
        self.role = role
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayMember':
        """Initialize a VPNGatewayMember object from a json dictionary."""
        args = {}
        if 'private_ip' in _dict:
            args['private_ip'] = IP.from_dict(_dict.get('private_ip'))
        if 'public_ip' in _dict:
            args['public_ip'] = IP.from_dict(_dict.get('public_ip'))
        else:
            raise ValueError(
                'Required property \'public_ip\' not present in VPNGatewayMember JSON'
            )
        if 'role' in _dict:
            args['role'] = _dict.get('role')
        else:
            raise ValueError(
                'Required property \'role\' not present in VPNGatewayMember JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayMember JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayMember object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'private_ip') and self.private_ip is not None:
            _dict['private_ip'] = self.private_ip.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, 'role') and self.role is not None:
            _dict['role'] = self.role
        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 VPNGatewayMember object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayMember') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayMember') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class RoleEnum(str, Enum):
        """
        The high availability role assigned to the VPN gateway member.
        """
        ACTIVE = 'active'
        STANDBY = 'standby'

    class StatusEnum(str, Enum):
        """
        The status of the VPN gateway member.
        """
        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'
        DELETING = 'deleting'


class VPNGatewayPatch():
    """
    VPNGatewayPatch.

    :attr str name: (optional) The user-defined name for this VPN gateway.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a VPNGatewayPatch object.

        :param str name: (optional) The user-defined name for this VPN gateway.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayPatch':
        """Initialize a VPNGatewayPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPatch object from 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 VPNGatewayPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayPrototype():
    """
    VPNGatewayPrototype.

    :attr str name: (optional) The user-defined name for this VPN gateway.
    :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 SubnetIdentity subnet: Identifies a subnet by a unique property.
    """

    def __init__(self,
                 subnet: 'SubnetIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a VPNGatewayPrototype object.

        :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.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VPNGatewayPrototypeVPNGatewayRouteModePrototype',
                'VPNGatewayPrototypeVPNGatewayPolicyModePrototype'
            ]))
        raise Exception(msg)


class Volume():
    """
    Volume.

    :attr int capacity: The capacity of the volume in gigabytes. The specified
          minimum and maximum capacity values for creating or updating volumes may expand
          in the future.
    :attr datetime created_at: The date and time that the volume was created.
    :attr str crn: The CRN for this volume.
    :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 str href: The URL for this volume.
    :attr str id: The unique identifier for this volume.
    :attr int iops: The bandwidth for the volume.
    :attr str name: The unique user-defined name for this volume.
    :attr VolumeProfileReference profile: The profile this volume uses.
    :attr ResourceGroupReference resource_group: The resource group for this volume.
    :attr str status: The status of the volume.
          The enumerated values for this property will expand in the future. When
          processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the volume on which the unexpected
          property value was encountered.
    :attr List[VolumeStatusReason] status_reasons: Array of reasons for the current
          status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :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,
            capacity: int,
            created_at: datetime,
            crn: str,
            encryption: str,
            href: str,
            id: str,
            iops: int,
            name: str,
            profile: 'VolumeProfileReference',
            resource_group: 'ResourceGroupReference',
            status: str,
            status_reasons: List['VolumeStatusReason'],
            volume_attachments: List['VolumeAttachmentReferenceVolumeContext'],
            zone: 'ZoneReference',
            *,
            encryption_key: 'EncryptionKeyReference' = None) -> None:
        """
        Initialize a Volume object.

        :param int capacity: The capacity of the volume in gigabytes. The specified
               minimum and maximum capacity values for creating or updating volumes may
               expand in the future.
        :param datetime created_at: The date and time that the volume was created.
        :param str crn: The CRN for this volume.
        :param str encryption: The type of encryption used on the volume.
        :param str href: The URL for this volume.
        :param str id: The unique identifier for this volume.
        :param int iops: The bandwidth for the volume.
        :param str name: The unique user-defined name for this volume.
        :param VolumeProfileReference profile: The profile this volume uses.
        :param ResourceGroupReference resource_group: The resource group for this
               volume.
        :param str status: The status of the volume.
               The enumerated values for this property will expand in the future. When
               processing this property, check for and log unknown values. Optionally halt
               processing and surface the error, or bypass the volume on which the
               unexpected property value was encountered.
        :param List[VolumeStatusReason] status_reasons: Array of reasons for the
               current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :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.capacity = capacity
        self.created_at = created_at
        self.crn = crn
        self.encryption = encryption
        self.encryption_key = encryption_key
        self.href = href
        self.id = id
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.status = status
        self.status_reasons = status_reasons
        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 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError(
                'Required property \'capacity\' 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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        else:
            raise ValueError(
                'Required property \'iops\' 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 'profile' in _dict:
            args['profile'] = VolumeProfileReference.from_dict(
                _dict.get('profile'))
        else:
            raise ValueError(
                'Required property \'profile\' 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 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in Volume JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [
                VolumeStatusReason.from_dict(x)
                for x in _dict.get('status_reasons')
            ]
        else:
            raise ValueError(
                'Required property \'status_reasons\' 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, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            _dict['profile'] = self.profile.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, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            _dict['status_reasons'] = [x.to_dict() for x in self.status_reasons]
        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.
        The enumerated values for this property will expand in the future. When processing
        this property, check for and log unknown values. Optionally halt processing and
        surface the error, or bypass the volume on which the unexpected property value was
        encountered.
        """
        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'
        PENDING_DELETION = 'pending_deletion'
        UNUSABLE = 'unusable'


class VolumeAttachment():
    """
    VolumeAttachment.

    :attr datetime created_at: The date and time that the volume was attached.
    :attr bool delete_volume_on_instance_delete: (optional) 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 str href: The URL for this volume attachment.
    :attr str id: The unique identifier for this volume attachment.
    :attr str name: The user-defined name for this volume attachment.
    :attr str status: The status of this volume attachment.
    :attr str type: The type of volume attachment.
    :attr VolumeReference volume: The attached volume.
    """

    def __init__(self,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 status: str,
                 type: str,
                 volume: 'VolumeReference',
                 *,
                 delete_volume_on_instance_delete: bool = None,
                 device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachment object.

        :param datetime created_at: The date and time that the volume was attached.
        :param str href: The URL for this volume attachment.
        :param str id: The unique identifier for this volume attachment.
        :param str name: The user-defined name for this volume attachment.
        :param str status: The status of this volume attachment.
        :param str type: The type of volume attachment.
        :param VolumeReference volume: The attached volume.
        :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.created_at = created_at
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.device = device
        self.href = href
        self.id = id
        self.name = name
        self.status = status
        self.type = type
        self.volume = volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachment':
        """Initialize a VolumeAttachment object from a json dictionary."""
        args = {}
        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 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(
                _dict.get('device'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachment JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachment JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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'
            )
        if 'volume' in _dict:
            args['volume'] = VolumeReference.from_dict(_dict.get('volume'))
        else:
            raise ValueError(
                'Required property \'volume\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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
        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 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'
        DELETING = 'deleting'
        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 VolumeAttachmentPatch():
    """
    VolumeAttachmentPatch.

    :attr bool delete_volume_on_instance_delete: (optional) If set to true, when
          deleting the instance the volume will also be deleted.
    :attr str name: (optional) The user-defined name for this volume attachment.
    """

    def __init__(self,
                 *,
                 delete_volume_on_instance_delete: bool = None,
                 name: str = None) -> None:
        """
        Initialize a VolumeAttachmentPatch object.

        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :param str name: (optional) The user-defined name for this volume
               attachment.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentPatch':
        """Initialize a VolumeAttachmentPatch object from a json dictionary."""
        args = {}
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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, '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 VolumeAttachmentPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceByImageContext():
    """
    VolumeAttachmentPrototypeInstanceByImageContext.

    :attr bool delete_volume_on_instance_delete: (optional) If set to true, when
          deleting the instance the volume will also be deleted.
    :attr str name: (optional) The user-defined name for this volume attachment.
    :attr VolumePrototypeInstanceByImageContext volume: A prototype object for a new
          volume.
    """

    def __init__(self,
                 volume: 'VolumePrototypeInstanceByImageContext',
                 *,
                 delete_volume_on_instance_delete: bool = None,
                 name: str = None) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceByImageContext object.

        :param VolumePrototypeInstanceByImageContext volume: A prototype object for
               a new volume.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :param str name: (optional) The user-defined name for this volume
               attachment.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'VolumeAttachmentPrototypeInstanceByImageContext':
        """Initialize a VolumeAttachmentPrototypeInstanceByImageContext object from a json dictionary."""
        args = {}
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 bool delete_volume_on_instance_delete: (optional) If set to true, when
          deleting the instance the volume will also be deleted.
    :attr str name: (optional) The user-defined name for this volume attachment.
    :attr VolumeAttachmentVolumePrototypeInstanceContext volume: The identity of the
          volume to attach to the instance, or a prototype object for a new
          volume.
    """

    def __init__(self,
                 volume: 'VolumeAttachmentVolumePrototypeInstanceContext',
                 *,
                 delete_volume_on_instance_delete: bool = None,
                 name: str = None) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceContext object.

        :param VolumeAttachmentVolumePrototypeInstanceContext volume: The identity
               of the volume to attach to the instance, or a prototype object for a new
               volume.
        :param bool delete_volume_on_instance_delete: (optional) If set to true,
               when deleting the instance the volume will also be deleted.
        :param str name: (optional) The user-defined name for this volume
               attachment.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'VolumeAttachmentPrototypeInstanceContext':
        """Initialize a VolumeAttachmentPrototypeInstanceContext object from a json dictionary."""
        args = {}
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get(
                'delete_volume_on_instance_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 VolumeAttachmentReferenceInstanceContext():
    """
    VolumeAttachmentReferenceInstanceContext.

    :attr VolumeAttachmentReferenceInstanceContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted and
          provides
          some supplementary information.
    :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 str href: The URL for this volume attachment.
    :attr str id: The unique identifier for this volume attachment.
    :attr str name: The user-defined name for this volume attachment.
    :attr VolumeReference volume: The attached volume.
    """

    def __init__(
            self,
            href: str,
            id: str,
            name: str,
            volume: 'VolumeReference',
            *,
            deleted: 'VolumeAttachmentReferenceInstanceContextDeleted' = None,
            device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachmentReferenceInstanceContext object.

        :param str href: The URL for this volume attachment.
        :param str id: The unique identifier for this volume attachment.
        :param str name: The user-defined name for this volume attachment.
        :param VolumeReference volume: The attached volume.
        :param VolumeAttachmentReferenceInstanceContextDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted and provides
               some supplementary information.
        :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.deleted = deleted
        self.device = device
        self.href = href
        self.id = id
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'VolumeAttachmentReferenceInstanceContext':
        """Initialize a VolumeAttachmentReferenceInstanceContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args[
                'deleted'] = VolumeAttachmentReferenceInstanceContextDeleted.from_dict(
                    _dict.get('deleted'))
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(
                _dict.get('device'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachmentReferenceInstanceContext JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 '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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'device') and self.device is not None:
            _dict['device'] = self.device.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 VolumeAttachmentReferenceInstanceContextDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a VolumeAttachmentReferenceInstanceContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'VolumeAttachmentReferenceInstanceContextDeleted':
        """Initialize a VolumeAttachmentReferenceInstanceContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in VolumeAttachmentReferenceInstanceContextDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceInstanceContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceInstanceContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'VolumeAttachmentReferenceInstanceContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'VolumeAttachmentReferenceInstanceContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentReferenceVolumeContext():
    """
    VolumeAttachmentReferenceVolumeContext.

    :attr bool delete_volume_on_instance_delete: If set to true, when deleting the
          instance the volume will also be deleted.
    :attr VolumeAttachmentReferenceVolumeContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted and
          provides
          some supplementary information.
    :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 str href: The URL for this volume attachment.
    :attr str id: The unique identifier for this volume attachment.
    :attr InstanceReference instance: The attached instance.
    :attr str name: The user-defined name for this volume attachment.
    :attr str type: The type of volume attachment.
    """

    def __init__(
            self,
            delete_volume_on_instance_delete: bool,
            href: str,
            id: str,
            instance: 'InstanceReference',
            name: str,
            type: str,
            *,
            deleted: 'VolumeAttachmentReferenceVolumeContextDeleted' = None,
            device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachmentReferenceVolumeContext object.

        :param bool delete_volume_on_instance_delete: If set to true, when deleting
               the instance the volume will also be deleted.
        :param str href: The URL for this volume attachment.
        :param str id: The unique identifier for this volume attachment.
        :param InstanceReference instance: The attached instance.
        :param str name: The user-defined name for this volume attachment.
        :param str type: The type of volume attachment.
        :param VolumeAttachmentReferenceVolumeContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        :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.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.deleted = deleted
        self.device = device
        self.href = href
        self.id = id
        self.instance = instance
        self.name = name
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentReferenceVolumeContext':
        """Initialize a VolumeAttachmentReferenceVolumeContext object from a json dictionary."""
        args = {}
        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 'deleted' in _dict:
            args[
                'deleted'] = VolumeAttachmentReferenceVolumeContextDeleted.from_dict(
                    _dict.get('deleted'))
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(
                _dict.get('device'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachmentReferenceVolumeContext JSON'
            )
        if 'instance' in _dict:
            args['instance'] = InstanceReference.from_dict(
                _dict.get('instance'))
        else:
            raise ValueError(
                'Required property \'instance\' 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 '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, '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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'device') and self.device is not None:
            _dict['device'] = self.device.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance') and self.instance is not None:
            _dict['instance'] = self.instance.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 VolumeAttachmentReferenceVolumeContextDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a VolumeAttachmentReferenceVolumeContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'VolumeAttachmentReferenceVolumeContextDeleted':
        """Initialize a VolumeAttachmentReferenceVolumeContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in VolumeAttachmentReferenceVolumeContextDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceVolumeContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceVolumeContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'VolumeAttachmentReferenceVolumeContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'VolumeAttachmentReferenceVolumeContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentVolumePrototypeInstanceContext():
    """
    The identity of the volume to attach to the instance, or a prototype object for a new
    volume.

    """

    def __init__(self) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContext object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity',
                'VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext'
            ]))
        raise Exception(msg)


class VolumeCollection():
    """
    VolumeCollection.

    :attr VolumeCollectionFirst first: A link 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 link to the next page of
          resources. This property is present 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 link 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 link to the next page of
               resources. This property is present 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeCollectionNext object.

        :param str href: The URL for a 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 VolumePatch():
    """
    VolumePatch.

    :attr str name: (optional) The unique user-defined name for this volume.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a VolumePatch object.

        :param str name: (optional) The unique user-defined name for this volume.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePatch':
        """Initialize a VolumePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumePatch object from 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 VolumePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfile():
    """
    VolumeProfile.

    :attr str family: (optional) The product family this volume profile belongs to.
    :attr str href: The URL for this volume profile.
    :attr str name: The globally unique name for this volume profile.
    """

    def __init__(self, href: str, name: str, *, family: str = None) -> None:
        """
        Initialize a VolumeProfile object.

        :param str href: The URL for this volume profile.
        :param str name: The globally unique name for this volume profile.
        :param str family: (optional) The product family this volume profile
               belongs to.
        """
        self.family = family
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfile':
        """Initialize a VolumeProfile object from a json dictionary."""
        args = {}
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfile JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VolumeProfile JSON')
        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, 'family') and self.family is not None:
            _dict['family'] = self.family
        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 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 link 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 link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[VolumeProfile] profiles: Collection of volume profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'VolumeProfileCollectionFirst',
                 limit: int,
                 profiles: List['VolumeProfile'],
                 total_count: int,
                 *,
                 next: 'VolumeProfileCollectionNext' = None) -> None:
        """
        Initialize a VolumeProfileCollection object.

        :param VolumeProfileCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[VolumeProfile] profiles: Collection of volume profiles.
        :param int total_count: The total number of resources across all pages.
        :param VolumeProfileCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.profiles = profiles
        self.total_count = total_count

    @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 '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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, 'profiles') and self.profiles is not None:
            _dict['profiles'] = [x.to_dict() for x in self.profiles]
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_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 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 link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeProfileCollectionFirst object.

        :param str href: The URL for a 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 link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeProfileCollectionNext object.

        :param str href: The URL for a 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 href: The URL for this volume profile.
    :attr str name: The globally unique name for this volume profile.
    """

    def __init__(self, href: str, name: str) -> None:
        """
        Initialize a VolumeProfileReference object.

        :param str href: The URL for this volume profile.
        :param str name: The globally unique name for this volume profile.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileReference':
        """Initialize a VolumeProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeProfileReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, '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 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 int iops: (optional) The bandwidth for the volume.
    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this 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 zone this volume will reside in.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 zone: 'ZoneIdentity',
                 *,
                 iops: int = None,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a VolumePrototype object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param ZoneIdentity zone: The zone this volume will reside in.
        :param int iops: (optional) The bandwidth for the volume.
        :param str name: (optional) The unique user-defined name for this 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 int capacity: (optional) The capacity of the volume in gigabytes. The
          specified minimum and maximum capacity values for creating or updating volumes
          may expand in the future.
    :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 but the image is encrypted, the image's
          `encryption_key` will be used. Otherwise, the `encryption` type for the
          volume will be `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 *,
                 capacity: int = None,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None,
                 name: str = None) -> None:
        """
        Initialize a VolumePrototypeInstanceByImageContext object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param int capacity: (optional) The capacity of the volume in gigabytes.
               The specified minimum and maximum capacity values for creating or updating
               volumes may expand in the future.
        :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 but the image is encrypted, the image's
               `encryption_key` will be used. Otherwise, the `encryption` type for the
               volume will be `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        :param str name: (optional) The unique user-defined name for this volume.
        """
        self.capacity = capacity
        self.encryption_key = encryption_key
        self.iops = iops
        self.name = name
        self.profile = profile

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeInstanceByImageContext':
        """Initialize a VolumePrototypeInstanceByImageContext object from a json dictionary."""
        args = {}
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        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'
            )
        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, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        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, '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()
        return _dict

    def _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 crn: The CRN for this volume.
    :attr VolumeReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this volume.
    :attr str id: The unique identifier for this volume.
    :attr str name: The unique user-defined name for this volume.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'VolumeReferenceDeleted' = None) -> None:
        """
        Initialize a VolumeReference object.

        :param str crn: The CRN for this volume.
        :param str href: The URL for this volume.
        :param str id: The unique identifier for this volume.
        :param str name: The unique user-defined name for this volume.
        :param VolumeReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReference':
        """Initialize a VolumeReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VolumeReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VolumeReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 VolumeReferenceDeleted():
    """
    If present, this property indicates the referenced resource has been deleted and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(self, more_info: str) -> None:
        """
        Initialize a VolumeReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReferenceDeleted':
        """Initialize a VolumeReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError(
                'Required property \'more_info\' not present in VolumeReferenceDeleted JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeStatusReason():
    """
    VolumeStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(self,
                 code: str,
                 message: str,
                 *,
                 more_info: str = None) -> None:
        """
        Initialize a VolumeStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeStatusReason':
        """Initialize a VolumeStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError(
                'Required property \'code\' not present in VolumeStatusReason JSON'
            )
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError(
                'Required property \'message\' not present in VolumeStatusReason JSON'
            )
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """
        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'


class Zone():
    """
    Zone.

    :attr str href: The URL for this zone.
    :attr str name: The globally unique name for this zone.
    :attr RegionReference region: The region this zone resides in.
    :attr str status: The availability status of this zone.
    """

    def __init__(self, href: str, name: str, region: 'RegionReference',
                 status: str) -> None:
        """
        Initialize a Zone object.

        :param str href: The URL for this zone.
        :param str name: The globally unique name for this zone.
        :param RegionReference region: The region this zone resides in.
        :param str status: The availability status of this zone.
        """
        self.href = href
        self.name = name
        self.region = region
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Zone':
        """Initialize a Zone object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in Zone JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, '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, '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 href: The URL for this zone.
    :attr str name: The globally unique name for this zone.
    """

    def __init__(self, href: str, name: str) -> None:
        """
        Initialize a ZoneReference object.

        :param str href: The URL for this zone.
        :param str name: The globally unique name for this zone.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ZoneReference':
        """Initialize a ZoneReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ZoneReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, '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 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 DedicatedHostGroupIdentityByCRN(DedicatedHostGroupIdentity):
    """
    DedicatedHostGroupIdentityByCRN.

    :attr str crn: The CRN for this dedicated host group.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a DedicatedHostGroupIdentityByCRN object.

        :param str crn: The CRN for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupIdentityByCRN':
        """Initialize a DedicatedHostGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in DedicatedHostGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupIdentityByCRN object from 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 DedicatedHostGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentityByHref(DedicatedHostGroupIdentity):
    """
    DedicatedHostGroupIdentityByHref.

    :attr str href: The URL for this dedicated host group.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostGroupIdentityByHref object.

        :param str href: The URL for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupIdentityByHref':
        """Initialize a DedicatedHostGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupIdentityByHref object from 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 DedicatedHostGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentityById(DedicatedHostGroupIdentity):
    """
    DedicatedHostGroupIdentityById.

    :attr str id: The unique identifier for this dedicated host group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a DedicatedHostGroupIdentityById object.

        :param str id: The unique identifier for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupIdentityById':
        """Initialize a DedicatedHostGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in DedicatedHostGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupIdentityById object from 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 DedicatedHostGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileIdentityByHref(DedicatedHostProfileIdentity):
    """
    DedicatedHostProfileIdentityByHref.

    :attr str href: The URL for this dedicated host profile.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a DedicatedHostProfileIdentityByHref object.

        :param str href: The URL for this dedicated host profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileIdentityByHref':
        """Initialize a DedicatedHostProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in DedicatedHostProfileIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileIdentityByHref object from 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 DedicatedHostProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileIdentityByName(DedicatedHostProfileIdentity):
    """
    DedicatedHostProfileIdentityByName.

    :attr str name: The globally unique name for this dedicated host profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a DedicatedHostProfileIdentityByName object.

        :param str name: The globally unique name for this dedicated host profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileIdentityByName':
        """Initialize a DedicatedHostProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in DedicatedHostProfileIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileIdentityByName object from 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 DedicatedHostProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileMemoryDependent(DedicatedHostProfileMemory):
    """
    The memory value for a dedicated host with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a DedicatedHostProfileMemoryDependent 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) -> 'DedicatedHostProfileMemoryDependent':
        """Initialize a DedicatedHostProfileMemoryDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileMemoryDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryDependent object from 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 DedicatedHostProfileMemoryDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryDependent') -> 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 DedicatedHostProfileMemoryEnum(DedicatedHostProfileMemory):
    """
    The permitted memory values (in gibibytes) for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a DedicatedHostProfileMemoryEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileMemoryEnum':
        """Initialize a DedicatedHostProfileMemoryEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in DedicatedHostProfileMemoryEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileMemoryEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in DedicatedHostProfileMemoryEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 DedicatedHostProfileMemoryEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryEnum') -> 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 DedicatedHostProfileMemoryFixed(DedicatedHostProfileMemory):
    """
    The memory (in gibibytes) for a dedicated host 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 DedicatedHostProfileMemoryFixed 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) -> 'DedicatedHostProfileMemoryFixed':
        """Initialize a DedicatedHostProfileMemoryFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileMemoryFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileMemoryFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryFixed object from 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 DedicatedHostProfileMemoryFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryFixed') -> 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 DedicatedHostProfileMemoryRange(DedicatedHostProfileMemory):
    """
    The permitted memory range (in gibibytes) for a dedicated host with this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a DedicatedHostProfileMemoryRange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileMemoryRange':
        """Initialize a DedicatedHostProfileMemoryRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in DedicatedHostProfileMemoryRange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in DedicatedHostProfileMemoryRange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in DedicatedHostProfileMemoryRange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in DedicatedHostProfileMemoryRange JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileMemoryRange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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
        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 DedicatedHostProfileMemoryRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryRange') -> 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 DedicatedHostProfileSocketDependent(DedicatedHostProfileSocket):
    """
    The CPU socket count for a dedicated host with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a DedicatedHostProfileSocketDependent 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) -> 'DedicatedHostProfileSocketDependent':
        """Initialize a DedicatedHostProfileSocketDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileSocketDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketDependent object from 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 DedicatedHostProfileSocketDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketDependent') -> 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 DedicatedHostProfileSocketEnum(DedicatedHostProfileSocket):
    """
    The permitted values for CPU socket count for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a DedicatedHostProfileSocketEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileSocketEnum':
        """Initialize a DedicatedHostProfileSocketEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in DedicatedHostProfileSocketEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileSocketEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in DedicatedHostProfileSocketEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 DedicatedHostProfileSocketEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketEnum') -> 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 DedicatedHostProfileSocketFixed(DedicatedHostProfileSocket):
    """
    The CPU socket count for a dedicated host 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 DedicatedHostProfileSocketFixed 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) -> 'DedicatedHostProfileSocketFixed':
        """Initialize a DedicatedHostProfileSocketFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileSocketFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileSocketFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketFixed object from 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 DedicatedHostProfileSocketFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketFixed') -> 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 DedicatedHostProfileSocketRange(DedicatedHostProfileSocket):
    """
    The permitted range for CPU socket count for a dedicated host with this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a DedicatedHostProfileSocketRange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileSocketRange':
        """Initialize a DedicatedHostProfileSocketRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in DedicatedHostProfileSocketRange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in DedicatedHostProfileSocketRange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in DedicatedHostProfileSocketRange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in DedicatedHostProfileSocketRange JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileSocketRange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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
        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 DedicatedHostProfileSocketRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketRange') -> 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 DedicatedHostProfileVCPUDependent(DedicatedHostProfileVCPU):
    """
    The VCPU count for a dedicated host with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a DedicatedHostProfileVCPUDependent 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) -> 'DedicatedHostProfileVCPUDependent':
        """Initialize a DedicatedHostProfileVCPUDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileVCPUDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUDependent object from 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 DedicatedHostProfileVCPUDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUDependent') -> 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 DedicatedHostProfileVCPUEnum(DedicatedHostProfileVCPU):
    """
    The permitted values for VCPU count for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a DedicatedHostProfileVCPUEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUEnum':
        """Initialize a DedicatedHostProfileVCPUEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in DedicatedHostProfileVCPUEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileVCPUEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in DedicatedHostProfileVCPUEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 DedicatedHostProfileVCPUEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUEnum') -> 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 DedicatedHostProfileVCPUFixed(DedicatedHostProfileVCPU):
    """
    The VCPU count for a dedicated host 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 DedicatedHostProfileVCPUFixed 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) -> 'DedicatedHostProfileVCPUFixed':
        """Initialize a DedicatedHostProfileVCPUFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileVCPUFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in DedicatedHostProfileVCPUFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUFixed object from 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 DedicatedHostProfileVCPUFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUFixed') -> 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 DedicatedHostProfileVCPURange(DedicatedHostProfileVCPU):
    """
    The permitted range for VCPU count for a dedicated host with this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a DedicatedHostProfileVCPURange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPURange':
        """Initialize a DedicatedHostProfileVCPURange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in DedicatedHostProfileVCPURange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in DedicatedHostProfileVCPURange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in DedicatedHostProfileVCPURange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in DedicatedHostProfileVCPURange JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in DedicatedHostProfileVCPURange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPURange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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
        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 DedicatedHostProfileVCPURange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPURange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPURange') -> 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 DedicatedHostPrototypeDedicatedHostByGroup(DedicatedHostPrototype):
    """
    DedicatedHostPrototypeDedicatedHostByGroup.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The unique user-defined name for this dedicated host.
          If unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileIdentity profile: The profile to use for this
          dedicated host.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr DedicatedHostGroupIdentity group: The dedicated host group for this
          dedicated host.
    """

    def __init__(self,
                 profile: 'DedicatedHostProfileIdentity',
                 group: 'DedicatedHostGroupIdentity',
                 *,
                 instance_placement_enabled: bool = None,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a DedicatedHostPrototypeDedicatedHostByGroup object.

        :param DedicatedHostProfileIdentity profile: The profile to use for this
               dedicated host.
        :param DedicatedHostGroupIdentity group: The dedicated host group for this
               dedicated host.
        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The unique user-defined name for this dedicated
               host. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.instance_placement_enabled = instance_placement_enabled
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.group = group

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'DedicatedHostPrototypeDedicatedHostByGroup':
        """Initialize a DedicatedHostPrototypeDedicatedHostByGroup object from a json dictionary."""
        args = {}
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get(
                'instance_placement_enabled')
        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 DedicatedHostPrototypeDedicatedHostByGroup JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'group' in _dict:
            args['group'] = _dict.get('group')
        else:
            raise ValueError(
                'Required property \'group\' not present in DedicatedHostPrototypeDedicatedHostByGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostPrototypeDedicatedHostByGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance_placement_enabled'
                  ) and self.instance_placement_enabled is not None:
            _dict[
                'instance_placement_enabled'] = self.instance_placement_enabled
        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, '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, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.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 DedicatedHostPrototypeDedicatedHostByGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'DedicatedHostPrototypeDedicatedHostByGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'DedicatedHostPrototypeDedicatedHostByGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostPrototypeDedicatedHostByZone(DedicatedHostPrototype):
    """
    DedicatedHostPrototypeDedicatedHostByZone.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The unique user-defined name for this dedicated host.
          If unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileIdentity profile: The profile to use for this
          dedicated host.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr DedicatedHostGroupPrototypeDedicatedHostByZoneContext group: (optional)
    :attr ZoneIdentity zone: The zone this dedicated host will reside in.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        instance_placement_enabled: bool = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        group: 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext' = None
    ) -> None:
        """
        Initialize a DedicatedHostPrototypeDedicatedHostByZone object.

        :param DedicatedHostProfileIdentity profile: The profile to use for this
               dedicated host.
        :param ZoneIdentity zone: The zone this dedicated host will reside in.
        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The unique user-defined name for this dedicated
               host. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param DedicatedHostGroupPrototypeDedicatedHostByZoneContext group:
               (optional)
        """
        # pylint: disable=super-init-not-called
        self.instance_placement_enabled = instance_placement_enabled
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.group = group
        self.zone = zone

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'DedicatedHostPrototypeDedicatedHostByZone':
        """Initialize a DedicatedHostPrototypeDedicatedHostByZone object from a json dictionary."""
        args = {}
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get(
                'instance_placement_enabled')
        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 DedicatedHostPrototypeDedicatedHostByZone JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'group' in _dict:
            args[
                'group'] = DedicatedHostGroupPrototypeDedicatedHostByZoneContext.from_dict(
                    _dict.get('group'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError(
                'Required property \'zone\' not present in DedicatedHostPrototypeDedicatedHostByZone JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostPrototypeDedicatedHostByZone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance_placement_enabled'
                  ) and self.instance_placement_enabled is not None:
            _dict[
                'instance_placement_enabled'] = self.instance_placement_enabled
        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, '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, 'group') and self.group is not None:
            _dict['group'] = self.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 DedicatedHostPrototypeDedicatedHostByZone object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'DedicatedHostPrototypeDedicatedHostByZone') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'DedicatedHostPrototypeDedicatedHostByZone') -> 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 EndpointGatewayReservedIPReservedIPIdentity(EndpointGatewayReservedIP):
    """
    Identifies a reserved IP by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById',
                'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref'
            ]))
        raise Exception(msg)


class EndpointGatewayReservedIPReservedIPPrototypeTargetContext(
        EndpointGatewayReservedIP):
    """
    EndpointGatewayReservedIPReservedIPPrototypeTargetContext.

    :attr bool auto_delete: (optional) If set to `true`, this reserved IP will be
          automatically deleted when the target is deleted or when the reserved IP is
          unbound.
    :attr str name: (optional) The user-defined name for this reserved IP. If not
          specified, the name will be a hyphenated list of randomly-selected words. Names
          must be unique within the subnet the reserved IP resides in. Names beginning
          with `ibm-` are reserved for provider-owned resources.
    :attr SubnetIdentity subnet: The subnet in which to create this reserved IP.
    """

    def __init__(self,
                 subnet: 'SubnetIdentity',
                 *,
                 auto_delete: bool = None,
                 name: str = None) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPPrototypeTargetContext object.

        :param SubnetIdentity subnet: The subnet in which to create this reserved
               IP.
        :param bool auto_delete: (optional) If set to `true`, this reserved IP will
               be automatically deleted when the target is deleted or when the reserved IP
               is unbound.
        :param str name: (optional) The user-defined name for this reserved IP. If
               not specified, the name will be a hyphenated list of randomly-selected
               words. Names must be unique within the subnet the reserved IP resides in.
               Names beginning with `ibm-` are reserved for provider-owned resources.
        """
        # pylint: disable=super-init-not-called
        self.auto_delete = auto_delete
        self.name = name
        self.subnet = subnet

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext':
        """Initialize a EndpointGatewayReservedIPReservedIPPrototypeTargetContext object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError(
                'Required property \'subnet\' not present in EndpointGatewayReservedIPReservedIPPrototypeTargetContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReservedIPReservedIPPrototypeTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 EndpointGatewayReservedIPReservedIPPrototypeTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayTargetPrototypeProviderCloudServiceIdentity(
        EndpointGatewayTargetPrototype):
    """
    EndpointGatewayTargetPrototypeProviderCloudServiceIdentity.

    :attr str resource_type: The type of target for this endpoint gateway.
    """

    def __init__(self, resource_type: str) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentity object.

        :param str resource_type: The type of target for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN'
            ]))
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'


class EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity(
        EndpointGatewayTargetPrototype):
    """
    EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity.

    :attr str resource_type: The type of target for this endpoint gateway.
    """

    def __init__(self, resource_type: str) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity object.

        :param str resource_type: The type of target for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName'
            ]))
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'


class EndpointGatewayTargetProviderCloudServiceReference(EndpointGatewayTarget):
    """
    EndpointGatewayTargetProviderCloudServiceReference.

    :attr str crn: The CRN for this provider cloud service, or the CRN for the
          user's instance of a provider cloud service.
    :attr str resource_type: The type of target.
    """

    def __init__(self, crn: str, resource_type: str) -> None:
        """
        Initialize a EndpointGatewayTargetProviderCloudServiceReference object.

        :param str crn: The CRN for this provider cloud service, or the CRN for the
               user's instance of a provider cloud service.
        :param str resource_type: The type of target.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.resource_type = resource_type

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'EndpointGatewayTargetProviderCloudServiceReference':
        """Initialize a EndpointGatewayTargetProviderCloudServiceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in EndpointGatewayTargetProviderCloudServiceReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in EndpointGatewayTargetProviderCloudServiceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetProviderCloudServiceReference object from 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
        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 EndpointGatewayTargetProviderCloudServiceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'EndpointGatewayTargetProviderCloudServiceReference'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'EndpointGatewayTargetProviderCloudServiceReference'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target.
        """
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'


class EndpointGatewayTargetProviderInfrastructureServiceReference(
        EndpointGatewayTarget):
    """
    The name of this provider infrastructure service.

    :attr str name: The name of a provider infrastructure service. Must be:
          - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
    :attr str resource_type: The type of target.
    """

    def __init__(self, name: str, resource_type: str) -> None:
        """
        Initialize a EndpointGatewayTargetProviderInfrastructureServiceReference object.

        :param str name: The name of a provider infrastructure service. Must be:
               - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
        :param str resource_type: The type of target.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'EndpointGatewayTargetProviderInfrastructureServiceReference':
        """Initialize a EndpointGatewayTargetProviderInfrastructureServiceReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in EndpointGatewayTargetProviderInfrastructureServiceReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in EndpointGatewayTargetProviderInfrastructureServiceReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetProviderInfrastructureServiceReference object from 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_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 EndpointGatewayTargetProviderInfrastructureServiceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'EndpointGatewayTargetProviderInfrastructureServiceReference'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'EndpointGatewayTargetProviderInfrastructureServiceReference'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target.
        """
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'


class FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(
        FloatingIPByTargetNetworkInterfaceIdentity):
    """
    FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this network interface.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref 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
    ) -> 'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from 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 FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById(
        FloatingIPByTargetNetworkInterfaceIdentity):
    """
    FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this network interface.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById 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
    ) -> 'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object from 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 FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FloatingIPByTargetNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> 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)
    :attr FloatingIPByTargetNetworkInterfaceIdentity target: The network interface
          this floating IP is to be bound to.
    """

    def __init__(self,
                 target: 'FloatingIPByTargetNetworkInterfaceIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByTarget object.

        :param FloatingIPByTargetNetworkInterfaceIdentity 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)
        """
        # 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)
    :attr ZoneIdentity zone: The zone this floating IP will reside in.
    """

    def __init__(self,
                 zone: 'ZoneIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByZone object.

        :param ZoneIdentity zone: The zone this floating IP will reside 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)
        """
        # 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 NetworkInterfaceReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this network interface.
    :attr str id: The unique identifier for this network interface.
    :attr str name: The user-defined name for this network interface.
    :attr str primary_ipv4_address: The primary IPv4 address.
    :attr str resource_type: The resource type.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 primary_ipv4_address: str,
                 resource_type: str,
                 *,
                 deleted: 'NetworkInterfaceReferenceDeleted' = None) -> None:
        """
        Initialize a FloatingIPTargetNetworkInterfaceReference object.

        :param str href: The URL for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str name: The user-defined name for this network interface.
        :param str primary_ipv4_address: The primary IPv4 address.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        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 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 crn: The CRN for this public gateway.
    :attr PublicGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this public gateway.
    :attr str id: The unique identifier 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,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'PublicGatewayReferenceDeleted' = None) -> None:
        """
        Initialize a FloatingIPTargetPublicGatewayReference object.

        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str id: The unique identifier for this public gateway.
        :param str name: The user-defined name for this public gateway.
        :param str resource_type: The resource type.
        :param PublicGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = PublicGatewayReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FloatingIPTargetPublicGatewayReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 FlowLogCollectorTargetPrototypeInstanceIdentity(
        FlowLogCollectorTargetPrototype):
    """
    Identifies a virtual server instance by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById',
                'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN',
                'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity(
        FlowLogCollectorTargetPrototype):
    """
    Identifies a network interface by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById',
                'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorTargetPrototypeSubnetIdentity(
        FlowLogCollectorTargetPrototype):
    """
    Identifies a subnet by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById',
                'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN',
                'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorTargetPrototypeVPCIdentity(FlowLogCollectorTargetPrototype
                                                ):
    """
    Identifies a VPC by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById',
                'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN',
                'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref'
            ]))
        raise Exception(msg)


class FlowLogCollectorTargetInstanceReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetInstanceReference.

    :attr str crn: The CRN for this virtual server instance.
    :attr InstanceReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'InstanceReferenceDeleted' = None) -> None:
        """
        Initialize a FlowLogCollectorTargetInstanceReference object.

        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        :param InstanceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'FlowLogCollectorTargetInstanceReference':
        """Initialize a FlowLogCollectorTargetInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetInstanceReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = InstanceReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetInstanceReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted and
          provides
          some supplementary information.
    :attr str href: The URL for this network interface.
    :attr str id: The unique identifier 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,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'NetworkInterfaceReferenceTargetContextDeleted' = None
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str name: The user-defined name for this network interface.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        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 'deleted' in _dict:
            args[
                'deleted'] = NetworkInterfaceReferenceTargetContextDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 crn: The CRN for this subnet.
    :attr SubnetReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this subnet.
    :attr str id: The unique identifier for this subnet.
    :attr str name: The user-defined name for this subnet.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'SubnetReferenceDeleted' = None) -> None:
        """
        Initialize a FlowLogCollectorTargetSubnetReference object.

        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str id: The unique identifier for this subnet.
        :param str name: The user-defined name for this subnet.
        :param SubnetReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetSubnetReference':
        """Initialize a FlowLogCollectorTargetSubnetReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetSubnetReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = SubnetReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetSubnetReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 crn: The CRN for this VPC.
    :attr VPCReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The unique user-defined name for this VPC.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'VPCReferenceDeleted' = None) -> None:
        """
        Initialize a FlowLogCollectorTargetVPCReference object.

        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str id: The unique identifier for this VPC.
        :param str name: The unique user-defined name for this VPC.
        :param VPCReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetVPCReference':
        """Initialize a FlowLogCollectorTargetVPCReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetVPCReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = VPCReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetVPCReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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)
    :attr str encrypted_data_key: (optional) A base64-encoded, encrypted
          representation of the key that was used to encrypt the data for this image.
          That representation is created by wrapping the key's value with the
          `encryption_key` root key (which must also be provided), using either [Key
          Protect](https://cloud.ibm.com/docs/key-protect?topic=key-protect-wrap-keys) or
          the
          [Hyper Protect Crypto
          Service](https://cloud.ibm.com/docs/services/hs-crypto?topic=hs-crypto-wrap-keys).
          If this property is not provided, the imported image is treated as unencrypted.
    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key that was used to wrap the data key (which is ultimately
          represented as `encrypted_data_key`). Additionally, the root key will be used to
          encrypt
          volumes created from this image (unless an alternate `encryption_key` is
          provided at
          volume creation).
          If this property is not provided, the imported image is treated as unencrypted.
    :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#list-operating-systems) included in
          this image.
    """

    def __init__(self,
                 file: 'ImageFilePrototype',
                 operating_system: 'OperatingSystemIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 encrypted_data_key: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = 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#list-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)
        :param str encrypted_data_key: (optional) A base64-encoded, encrypted
               representation of the key that was used to encrypt the data for this image.
               That representation is created by wrapping the key's value with the
               `encryption_key` root key (which must also be provided), using either [Key
               Protect](https://cloud.ibm.com/docs/key-protect?topic=key-protect-wrap-keys)
               or the
               [Hyper Protect Crypto
               Service](https://cloud.ibm.com/docs/services/hs-crypto?topic=hs-crypto-wrap-keys).
               If this property is not provided, the imported image is treated as
               unencrypted.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key that was used to wrap the data key (which is ultimately
               represented as `encrypted_data_key`). Additionally, the root key will be
               used to encrypt
               volumes created from this image (unless an alternate `encryption_key` is
               provided at
               volume creation).
               If this property is not provided, the imported image is treated as
               unencrypted.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.encrypted_data_key = encrypted_data_key
        self.encryption_key = encryption_key
        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 'encrypted_data_key' in _dict:
            args['encrypted_data_key'] = _dict.get('encrypted_data_key')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        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,
                'encrypted_data_key') and self.encrypted_data_key is not None:
            _dict['encrypted_data_key'] = self.encrypted_data_key
        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, '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 InstanceGroupManagerActionPatchScheduledActionPatch(
        InstanceGroupManagerActionPatch):
    """
    InstanceGroupManagerActionPatchScheduledActionPatch.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr InstanceGroupManagerScheduledActionGroupPatch group: (optional)
    :attr InstanceGroupManagerScheduledActionByManagerPatchManager manager:
          (optional)
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    """

    def __init__(
            self,
            *,
            name: str = None,
            cron_spec: str = None,
            group: 'InstanceGroupManagerScheduledActionGroupPatch' = None,
            manager:
        'InstanceGroupManagerScheduledActionByManagerPatchManager' = None,
            run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPatchScheduledActionPatch object.

        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param InstanceGroupManagerScheduledActionGroupPatch group: (optional)
        :param InstanceGroupManagerScheduledActionByManagerPatchManager manager:
               (optional)
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.cron_spec = cron_spec
        self.group = group
        self.manager = manager
        self.run_at = run_at

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'InstanceGroupManagerActionPatchScheduledActionPatch':
        """Initialize a InstanceGroupManagerActionPatchScheduledActionPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'group' in _dict:
            args[
                'group'] = InstanceGroupManagerScheduledActionGroupPatch.from_dict(
                    _dict.get('group'))
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        if 'run_at' in _dict:
            args['run_at'] = string_to_datetime(_dict.get('run_at'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPatchScheduledActionPatch object from 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, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'group') and self.group is not None:
            _dict['group'] = self.group.to_dict()
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.to_dict()
        if hasattr(self, 'run_at') and self.run_at is not None:
            _dict['run_at'] = datetime_to_string(self.run_at)
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionPatchScheduledActionPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'InstanceGroupManagerActionPatchScheduledActionPatch'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'InstanceGroupManagerActionPatchScheduledActionPatch'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototype(
        InstanceGroupManagerActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototype.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    """

    def __init__(self, *, name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototype object.

        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt',
                'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec'
            ]))
        raise Exception(msg)


class InstanceGroupManagerActionScheduledAction(InstanceGroupManagerAction):
    """
    InstanceGroupManagerActionScheduledAction.

    :attr bool auto_delete: If set to `true`, this scheduled action will be
          automatically deleted after it has finished and the `auto_delete_timeout` time
          has passed.
    :attr int auto_delete_timeout: Amount of time in hours that are required to pass
          before the scheduled action will be automatically deleted once it has finished.
          If this value is 0, the action will be deleted on completion.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The user-defined name for this instance group manager action.
          Names must be unique within the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was modified.
    :attr str action_type: The type of action for the instance group.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr datetime last_applied_at: (optional) The date and time the scheduled
          action was last applied. If empty the action has never been applied.
    :attr datetime next_run_at: (optional) The date and time the scheduled action
          will next run. If empty the system is currently calculating the next run time.
    """

    def __init__(self,
                 auto_delete: bool,
                 auto_delete_timeout: int,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 status: str,
                 updated_at: datetime,
                 action_type: str,
                 *,
                 cron_spec: str = None,
                 last_applied_at: datetime = None,
                 next_run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionScheduledAction object.

        :param bool auto_delete: If set to `true`, this scheduled action will be
               automatically deleted after it has finished and the `auto_delete_timeout`
               time has passed.
        :param int auto_delete_timeout: Amount of time in hours that are required
               to pass before the scheduled action will be automatically deleted once it
               has finished. If this value is 0, the action will be deleted on completion.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The user-defined name for this instance group manager
               action. Names must be unique within the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was modified.
        :param str action_type: The type of action for the instance group.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param datetime last_applied_at: (optional) The date and time the scheduled
               action was last applied. If empty the action has never been applied.
        :param datetime next_run_at: (optional) The date and time the scheduled
               action will next run. If empty the system is currently calculating the next
               run time.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerActionScheduledActionGroup',
                'InstanceGroupManagerActionScheduledActionManager'
            ]))
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'

    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """
        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'

    class ActionTypeEnum(str, Enum):
        """
        The type of action for the instance group.
        """
        SCHEDULED = 'scheduled'


class InstanceGroupManagerAutoScale(InstanceGroupManager):
    """
    InstanceGroupManagerAutoScale.

    :attr datetime created_at: The date and time that the instance group manager was
          created.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr bool management_enabled: If set to `true`, this manager will control the
          instance group.
    :attr str name: The user-defined name for this instance group manager. Names
          must be unique within the instance group.
    :attr datetime updated_at: The date and time that the instance group manager was
          updated.
    :attr int aggregation_window: The time window in seconds to aggregate metrics
          prior to evaluation.
    :attr int cooldown: The duration of time in seconds to pause further scale
          actions after scaling has taken place.
    :attr str manager_type: The type of instance group manager.
    :attr int max_membership_count: The maximum number of members in a managed
          instance group.
    :attr int min_membership_count: The minimum number of members in a managed
          instance group.
    :attr List[InstanceGroupManagerPolicyReference] policies: The policies of the
          instance group manager.
    """

    def __init__(self, created_at: datetime, href: str, id: str,
                 management_enabled: bool, name: str, updated_at: datetime,
                 aggregation_window: int, cooldown: int, manager_type: str,
                 max_membership_count: int, min_membership_count: int,
                 policies: List['InstanceGroupManagerPolicyReference']) -> None:
        """
        Initialize a InstanceGroupManagerAutoScale object.

        :param datetime created_at: The date and time that the instance group
               manager was created.
        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param bool management_enabled: If set to `true`, this manager will control
               the instance group.
        :param str name: The user-defined name for this instance group manager.
               Names must be unique within the instance group.
        :param datetime updated_at: The date and time that the instance group
               manager was updated.
        :param int aggregation_window: The time window in seconds to aggregate
               metrics prior to evaluation.
        :param int cooldown: The duration of time in seconds to pause further scale
               actions after scaling has taken place.
        :param str manager_type: The type of instance group manager.
        :param int max_membership_count: The maximum number of members in a managed
               instance group.
        :param int min_membership_count: The minimum number of members in a managed
               instance group.
        :param List[InstanceGroupManagerPolicyReference] policies: The policies of
               the instance group manager.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.management_enabled = management_enabled
        self.name = name
        self.updated_at = updated_at
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.manager_type = manager_type
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.policies = policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerAutoScale':
        """Initialize a InstanceGroupManagerAutoScale object from a json dictionary."""
        args = {}
        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 InstanceGroupManagerAutoScale JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        else:
            raise ValueError(
                'Required property \'management_enabled\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        else:
            raise ValueError(
                'Required property \'aggregation_window\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        else:
            raise ValueError(
                'Required property \'cooldown\' not present in InstanceGroupManagerAutoScale JSON'
            )
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError(
                'Required property \'manager_type\' not present in InstanceGroupManagerAutoScale JSON'
            )
        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 InstanceGroupManagerAutoScale JSON'
            )
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        else:
            raise ValueError(
                'Required property \'min_membership_count\' not present in InstanceGroupManagerAutoScale 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 InstanceGroupManagerAutoScale JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerAutoScale object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(
                self,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        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, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        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, '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 InstanceGroupManagerAutoScale object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerAutoScale') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerAutoScale') -> 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 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 datetime created_at: The date and time that the instance group manager
          policy was created.
    :attr str href: The URL for this instance group manager policy.
    :attr str id: The unique identifier 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 datetime updated_at: The date and time that the instance group manager
          policy was updated.
    :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, created_at: datetime, href: str, id: str, name: str,
                 updated_at: datetime, metric_type: str, metric_value: int,
                 policy_type: str) -> None:
        """
        Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object.

        :param datetime created_at: The date and time that the instance group
               manager policy was created.
        :param str href: The URL for this instance group manager policy.
        :param str id: The unique identifier 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 datetime updated_at: The date and time that the instance group
               manager policy was updated.
        :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.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.updated_at = updated_at
        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 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError(
                'Required property \'created_at\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' 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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        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 bool management_enabled: (optional) If set to `true`, this manager will
          control the instance group.
    :attr str name: (optional) The user-defined name for this instance group
          manager. Names must be unique within 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 str manager_type: The type of instance group manager.
    :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.
    """

    def __init__(self,
                 manager_type: str,
                 max_membership_count: int,
                 *,
                 management_enabled: bool = None,
                 name: str = None,
                 aggregation_window: int = None,
                 cooldown: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object.

        :param str manager_type: The type of instance group manager.
        :param int max_membership_count: The maximum number of members in a managed
               instance group.
        :param bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        :param str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within 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.management_enabled = management_enabled
        self.name = name
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.manager_type = manager_type
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype':
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object from a json dictionary."""
        args = {}
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError(
                'Required property \'manager_type\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON'
            )
        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')
        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,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        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
        return _dict

    def _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 InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype(
        InstanceGroupManagerPrototype):
    """
    InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype.

    :attr bool management_enabled: (optional) If set to `true`, this manager will
          control the instance group.
    :attr str name: (optional) The user-defined name for this instance group
          manager. Names must be unique within the instance group.
    :attr str manager_type: The type of instance group manager.
    """

    def __init__(self,
                 manager_type: str,
                 *,
                 management_enabled: bool = None,
                 name: str = None) -> None:
        """
        Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object.

        :param str manager_type: The type of instance group manager.
        :param bool management_enabled: (optional) If set to `true`, this manager
               will control the instance group.
        :param str name: (optional) The user-defined name for this instance group
               manager. Names must be unique within the instance group.
        """
        # pylint: disable=super-init-not-called
        self.management_enabled = management_enabled
        self.name = name
        self.manager_type = manager_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype':
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object from a json dictionary."""
        args = {}
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError(
                'Required property \'manager_type\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(
                self,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype'
    ) -> 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.
        """
        SCHEDULED = 'scheduled'


class InstanceGroupManagerScheduled(InstanceGroupManager):
    """
    InstanceGroupManagerScheduled.

    :attr datetime created_at: The date and time that the instance group manager was
          created.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr bool management_enabled: If set to `true`, this manager will control the
          instance group.
    :attr str name: The user-defined name for this instance group manager. Names
          must be unique within the instance group.
    :attr datetime updated_at: The date and time that the instance group manager was
          updated.
    :attr List[InstanceGroupManagerActionReference] actions: The actions of the
          instance group manager.
    :attr str manager_type: The type of instance group manager.
    """

    def __init__(self, created_at: datetime, href: str, id: str,
                 management_enabled: bool, name: str, updated_at: datetime,
                 actions: List['InstanceGroupManagerActionReference'],
                 manager_type: str) -> None:
        """
        Initialize a InstanceGroupManagerScheduled object.

        :param datetime created_at: The date and time that the instance group
               manager was created.
        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param bool management_enabled: If set to `true`, this manager will control
               the instance group.
        :param str name: The user-defined name for this instance group manager.
               Names must be unique within the instance group.
        :param datetime updated_at: The date and time that the instance group
               manager was updated.
        :param List[InstanceGroupManagerActionReference] actions: The actions of
               the instance group manager.
        :param str manager_type: The type of instance group manager.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.management_enabled = management_enabled
        self.name = name
        self.updated_at = updated_at
        self.actions = actions
        self.manager_type = manager_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduled':
        """Initialize a InstanceGroupManagerScheduled object from a json dictionary."""
        args = {}
        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 InstanceGroupManagerScheduled JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerScheduled JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerScheduled JSON'
            )
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        else:
            raise ValueError(
                'Required property \'management_enabled\' not present in InstanceGroupManagerScheduled JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerScheduled JSON'
            )
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' not present in InstanceGroupManagerScheduled JSON'
            )
        if 'actions' in _dict:
            args['actions'] = [
                InstanceGroupManagerActionReference.from_dict(x)
                for x in _dict.get('actions')
            ]
        else:
            raise ValueError(
                'Required property \'actions\' not present in InstanceGroupManagerScheduled JSON'
            )
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError(
                'Required property \'manager_type\' not present in InstanceGroupManagerScheduled JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduled object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(
                self,
                'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'actions') and self.actions is not None:
            _dict['actions'] = [x.to_dict() for x in self.actions]
        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 InstanceGroupManagerScheduled object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduled') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduled') -> 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.
        """
        SCHEDULED = 'scheduled'


class InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototype(
        InstanceGroupManagerScheduledActionByManagerManager):
    """
    The identity of the auto scale manager to update and the property or properties to be
    updated. Exactly one of `id` or `href` must be provided in addition to at least one of
    `min_membership_count` and `max_membership_count`.

    :attr int max_membership_count: (optional) The maximum number of members the
          instance group should have at the scheduled time.
    :attr int min_membership_count: (optional) The minimum number of members the
          instance group should have at the scheduled time.
    """

    def __init__(self,
                 *,
                 max_membership_count: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototype object.

        :param int max_membership_count: (optional) The maximum number of members
               the instance group should have at the scheduled time.
        :param int min_membership_count: (optional) The minimum number of members
               the instance group should have at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById',
                'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref'
            ]))
        raise Exception(msg)


class InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch(
        InstanceGroupManagerScheduledActionByManagerPatchManager):
    """
    InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch.

    :attr int max_membership_count: (optional) The maximum number of members the
          instance group should have at the scheduled time.
    :attr int min_membership_count: (optional) The minimum number of members the
          instance group should have at the scheduled time.
    """

    def __init__(self,
                 *,
                 max_membership_count: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch object.

        :param int max_membership_count: (optional) The maximum number of members
               the instance group should have at the scheduled time.
        :param int min_membership_count: (optional) The minimum number of members
               the instance group should have at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch':
        """Initialize a InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch object from a json dictionary."""
        args = {}
        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')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerScheduledActionByManagerPatchManagerAutoScalePatch'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionManagerManagerAutoScale(
        InstanceGroupManagerScheduledActionManagerManager):
    """
    InstanceGroupManagerScheduledActionManagerManagerAutoScale.

    :attr InstanceGroupManagerReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier 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 int max_membership_count: (optional) The maximum number of members the
          instance group should have at the scheduled time.
    :attr int min_membership_count: (optional) The minimum number of members the
          instance group should have at the scheduled time.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'InstanceGroupManagerReferenceDeleted' = None,
                 max_membership_count: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerManagerAutoScale object.

        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier 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 InstanceGroupManagerReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        :param int max_membership_count: (optional) The maximum number of members
               the instance group should have at the scheduled time.
        :param int min_membership_count: (optional) The minimum number of members
               the instance group should have at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerScheduledActionManagerManagerAutoScale':
        """Initialize a InstanceGroupManagerScheduledActionManagerManagerAutoScale object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupManagerReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerScheduledActionManagerManagerAutoScale JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerScheduledActionManagerManagerAutoScale JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerScheduledActionManagerManagerAutoScale JSON'
            )
        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')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionManagerManagerAutoScale object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionManagerManagerAutoScale object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'InstanceGroupManagerScheduledActionManagerManagerAutoScale'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'InstanceGroupManagerScheduledActionManagerManagerAutoScale'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePatchProfileInstanceProfileIdentityByHref(InstancePatchProfile):
    """
    InstancePatchProfileInstanceProfileIdentityByHref.

    :attr str href: The URL for this virtual server instance profile.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstancePatchProfileInstanceProfileIdentityByHref 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) -> 'InstancePatchProfileInstanceProfileIdentityByHref':
        """Initialize a InstancePatchProfileInstanceProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstancePatchProfileInstanceProfileIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePatchProfileInstanceProfileIdentityByHref object from 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 InstancePatchProfileInstanceProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'InstancePatchProfileInstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'InstancePatchProfileInstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePatchProfileInstanceProfileIdentityByName(InstancePatchProfile):
    """
    InstancePatchProfileInstanceProfileIdentityByName.

    :attr str name: The globally unique name for this virtual server instance
          profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a InstancePatchProfileInstanceProfileIdentityByName object.

        :param str name: The globally unique name for this virtual server instance
               profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstancePatchProfileInstanceProfileIdentityByName':
        """Initialize a InstancePatchProfileInstanceProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstancePatchProfileInstanceProfileIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePatchProfileInstanceProfileIdentityByName object from 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 InstancePatchProfileInstanceProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'InstancePatchProfileInstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'InstancePatchProfileInstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentity(
        InstancePlacementTargetPrototype):
    """
    Identifies a dedicated host group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById',
                'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN',
                'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref'
            ]))
        raise Exception(msg)


class InstancePlacementTargetPrototypeDedicatedHostIdentity(
        InstancePlacementTargetPrototype):
    """
    Identifies a dedicated host by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById',
                'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN',
                'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref'
            ]))
        raise Exception(msg)


class InstanceProfileBandwidthDependent(InstanceProfileBandwidth):
    """
    The total bandwidth shared across the network interfaces and storage volumes 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 int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a InstanceProfileBandwidthEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthEnum':
        """Initialize a InstanceProfileBandwidthEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileBandwidthEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 and
    storage volumes 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 and storage volumes of an instance with this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a InstanceProfileBandwidthRange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthRange':
        """Initialize a InstanceProfileBandwidthRange object from a json dictionary."""
        args = {}
        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'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, '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
        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 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 InstanceProfileDiskQuantityDependent(InstanceProfileDiskQuantity):
    """
    The number of disks of this configuration for an instance with this profile depends on
    its instance configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a InstanceProfileDiskQuantityDependent 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) -> 'InstanceProfileDiskQuantityDependent':
        """Initialize a InstanceProfileDiskQuantityDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskQuantityDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityDependent object from 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 InstanceProfileDiskQuantityDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityDependent') -> 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 InstanceProfileDiskQuantityEnum(InstanceProfileDiskQuantity):
    """
    The permitted the number of disks of this configuration for an instance with this
    profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a InstanceProfileDiskQuantityEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskQuantityEnum':
        """Initialize a InstanceProfileDiskQuantityEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileDiskQuantityEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskQuantityEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileDiskQuantityEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 InstanceProfileDiskQuantityEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityEnum') -> 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 InstanceProfileDiskQuantityFixed(InstanceProfileDiskQuantity):
    """
    The number of disks of this configuration 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 InstanceProfileDiskQuantityFixed 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) -> 'InstanceProfileDiskQuantityFixed':
        """Initialize a InstanceProfileDiskQuantityFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskQuantityFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfileDiskQuantityFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityFixed object from 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 InstanceProfileDiskQuantityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityFixed') -> 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 InstanceProfileDiskQuantityRange(InstanceProfileDiskQuantity):
    """
    The permitted range for the number of disks of this configuration for an instance with
    this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a InstanceProfileDiskQuantityRange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskQuantityRange':
        """Initialize a InstanceProfileDiskQuantityRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileDiskQuantityRange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in InstanceProfileDiskQuantityRange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in InstanceProfileDiskQuantityRange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in InstanceProfileDiskQuantityRange JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskQuantityRange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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
        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 InstanceProfileDiskQuantityRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityRange') -> 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 InstanceProfileDiskSizeDependent(InstanceProfileDiskSize):
    """
    The disk size in GB (gigabytes) of this configuration for an instance with this
    profile depends on its instance configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a InstanceProfileDiskSizeDependent 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) -> 'InstanceProfileDiskSizeDependent':
        """Initialize a InstanceProfileDiskSizeDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskSizeDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeDependent object from 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 InstanceProfileDiskSizeDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeDependent') -> 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 InstanceProfileDiskSizeEnum(InstanceProfileDiskSize):
    """
    The permitted disk size in GB (gigabytes) of this configuration for an instance with
    this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a InstanceProfileDiskSizeEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSizeEnum':
        """Initialize a InstanceProfileDiskSizeEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileDiskSizeEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskSizeEnum JSON'
            )
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError(
                'Required property \'values\' not present in InstanceProfileDiskSizeEnum JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 InstanceProfileDiskSizeEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeEnum') -> 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 InstanceProfileDiskSizeFixed(InstanceProfileDiskSize):
    """
    The size of the disk in GB (gigabytes).

    :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 InstanceProfileDiskSizeFixed 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) -> 'InstanceProfileDiskSizeFixed':
        """Initialize a InstanceProfileDiskSizeFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskSizeFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in InstanceProfileDiskSizeFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeFixed object from 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 InstanceProfileDiskSizeFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeFixed') -> 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 InstanceProfileDiskSizeRange(InstanceProfileDiskSize):
    """
    The permitted range for the disk size of this configuration in GB (gigabytes) for an
    instance with this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a InstanceProfileDiskSizeRange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSizeRange':
        """Initialize a InstanceProfileDiskSizeRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileDiskSizeRange JSON'
            )
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError(
                'Required property \'max\' not present in InstanceProfileDiskSizeRange JSON'
            )
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError(
                'Required property \'min\' not present in InstanceProfileDiskSizeRange JSON'
            )
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError(
                'Required property \'step\' not present in InstanceProfileDiskSizeRange JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in InstanceProfileDiskSizeRange JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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
        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 InstanceProfileDiskSizeRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeRange') -> 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 globally unique name for this virtual server instance
          profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a InstanceProfileIdentityByName object.

        :param str name: The globally unique 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 gibibytes) for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a InstanceProfileMemoryEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryEnum':
        """Initialize a InstanceProfileMemoryEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileMemoryEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 gibibytes) 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 gibibytes) for an instance with this profile.

    :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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a InstanceProfileMemoryRange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryRange':
        """Initialize a InstanceProfileMemoryRange object from a json dictionary."""
        args = {}
        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'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, '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
        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 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 int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(self, default: int, type: str, values: List[int]) -> None:
        """
        Initialize a InstanceProfileVCPUEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUEnum':
        """Initialize a InstanceProfileVCPUEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError(
                'Required property \'default\' not present in InstanceProfileVCPUEnum JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 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.
    :attr str type: The type for this profile field.
    """

    def __init__(self, default: int, max: int, min: int, step: int,
                 type: str) -> None:
        """
        Initialize a InstanceProfileVCPURange object.

        :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.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPURange':
        """Initialize a InstanceProfileVCPURange object from a json dictionary."""
        args = {}
        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'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' 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, '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
        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 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 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 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[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupIdentity resource_group: (optional)
    :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 VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: The identity of the image to use when provisioning
          the virtual server instance.
    :attr NetworkInterfacePrototype primary_network_interface: Primary network
          interface.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        keys: List['KeyIdentity'] = None,
        name: str = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_data: str = None,
        volume_attachments: List[
            'VolumeAttachmentPrototypeInstanceContext'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment:
        'VolumeAttachmentPrototypeInstanceByImageContext' = None
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByImage object.

        :param ImageIdentity image: The identity of the image to use when
               provisioning the virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: Primary network
               interface.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :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 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[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param ResourceGroupIdentity resource_group: (optional)
        :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.keys = keys
        self.name = name
        self.network_interfaces = network_interfaces
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByImage':
        """Initialize a InstancePrototypeInstanceByImage object from a json dictionary."""
        args = {}
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        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 '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'
            )
        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'
            )
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        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, '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, '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, '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, '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()
        return _dict

    def _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 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 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[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupIdentity resource_group: (optional)
    :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 VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: (optional) The identity of the image to use when
          provisioning the virtual server instance.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) Primary
          network interface.
    :attr InstanceTemplateIdentity source_template: Identifies an instance template
          by a unique property.
    :attr ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(self,
                 source_template: 'InstanceTemplateIdentity',
                 *,
                 keys: List['KeyIdentity'] = None,
                 name: str = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 placement_target: 'InstancePlacementTargetPrototype' = None,
                 profile: 'InstanceProfileIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 boot_volume_attachment:
                 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
                 image: 'ImageIdentity' = None,
                 primary_network_interface: 'NetworkInterfacePrototype' = None,
                 zone: 'ZoneIdentity' = None) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceTemplate object.

        :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 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[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param ResourceGroupIdentity resource_group: (optional)
        :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.
        :param ImageIdentity image: (optional) The identity of the image to use
               when provisioning the virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: (optional)
               Primary network interface.
        :param ZoneIdentity zone: (optional) The zone this virtual server instance
               will reside in.
        """
        # pylint: disable=super-init-not-called
        self.keys = keys
        self.name = name
        self.network_interfaces = network_interfaces
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.primary_network_interface = primary_network_interface
        self.source_template = source_template
        self.zone = zone

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstancePrototypeInstanceBySourceTemplate':
        """Initialize a InstancePrototypeInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        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 '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 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError(
                'Required property \'source_template\' not present in InstancePrototypeInstanceBySourceTemplate JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        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, '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, '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, '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, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.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()
        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 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 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 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[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupIdentity resource_group: (optional)
    :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 VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: The identity of the image to use when provisioning
          the virtual server instance.
    :attr NetworkInterfacePrototype primary_network_interface: Primary network
          interface.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        keys: List['KeyIdentity'] = None,
        name: str = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_data: str = None,
        volume_attachments: List[
            'VolumeAttachmentPrototypeInstanceContext'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment:
        'VolumeAttachmentPrototypeInstanceByImageContext' = None
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceByImage object.

        :param ImageIdentity image: The identity of the image to use when
               provisioning the virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: Primary network
               interface.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :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 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[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param ResourceGroupIdentity resource_group: (optional)
        :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.keys = keys
        self.name = name
        self.network_interfaces = network_interfaces
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceTemplatePrototypeInstanceByImage':
        """Initialize a InstanceTemplatePrototypeInstanceByImage object from a json dictionary."""
        args = {}
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        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 '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'
            )
        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'
            )
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        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, '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, '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, '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, '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()
        return _dict

    def _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 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 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[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupIdentity resource_group: (optional)
    :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 VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: (optional) The identity of the image to use when
          provisioning the virtual server instance.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) Primary
          network interface.
    :attr InstanceTemplateIdentity source_template: Identifies an instance template
          by a unique property.
    :attr ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(self,
                 source_template: 'InstanceTemplateIdentity',
                 *,
                 keys: List['KeyIdentity'] = None,
                 name: str = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 placement_target: 'InstancePlacementTargetPrototype' = None,
                 profile: 'InstanceProfileIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 boot_volume_attachment:
                 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
                 image: 'ImageIdentity' = None,
                 primary_network_interface: 'NetworkInterfacePrototype' = None,
                 zone: 'ZoneIdentity' = None) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceBySourceTemplate object.

        :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 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[NetworkInterfacePrototype] network_interfaces: (optional)
               Collection of additional network interfaces to create for the virtual
               server instance.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The profile to use for
               this virtual server instance.
        :param ResourceGroupIdentity resource_group: (optional)
        :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.
        :param ImageIdentity image: (optional) The identity of the image to use
               when provisioning the virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: (optional)
               Primary network interface.
        :param ZoneIdentity zone: (optional) The zone this virtual server instance
               will reside in.
        """
        # pylint: disable=super-init-not-called
        self.keys = keys
        self.name = name
        self.network_interfaces = network_interfaces
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.primary_network_interface = primary_network_interface
        self.source_template = source_template
        self.zone = zone

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceTemplatePrototypeInstanceBySourceTemplate':
        """Initialize a InstanceTemplatePrototypeInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        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 '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 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError(
                'Required property \'source_template\' not present in InstanceTemplatePrototypeInstanceBySourceTemplate JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        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, '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, '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, '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, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.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()
        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 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 datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier 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 str name: The unique user-defined name for this instance template.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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 VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: The identity of the image to use when provisioning
          the virtual server instance.
    :attr NetworkInterfacePrototype primary_network_interface: Primary network
          interface.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        image: 'ImageIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        keys: List['KeyIdentity'] = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        placement_target: 'InstancePlacementTargetPrototype' = 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 datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param ImageIdentity image: The identity of the image to use when
               provisioning the virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: Primary network
               interface.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :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 InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use 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.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.keys = keys
        self.name = name
        self.network_interfaces = network_interfaces
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByImage':
        """Initialize a InstanceTemplateInstanceByImage object from a json dictionary."""
        args = {}
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceTemplateInstanceByImage JSON'
            )
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        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 '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 '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'
            )
        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'
            )
        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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        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, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.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, '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, '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()
        return _dict

    def _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 datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier 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 str name: The unique user-defined name for this instance template.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) Collection
          of additional network interfaces to create for the virtual server instance.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The profile to use for this
          virtual server instance.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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 VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment for the virtual server instance.
    :attr ImageIdentity image: (optional) The identity of the image to use when
          provisioning the virtual server instance.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) Primary
          network interface.
    :attr InstanceTemplateIdentity source_template: Identifies an instance template
          by a unique property.
    :attr ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(self,
                 created_at: datetime,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 source_template: 'InstanceTemplateIdentity',
                 *,
                 keys: List['KeyIdentity'] = None,
                 network_interfaces: List['NetworkInterfacePrototype'] = None,
                 placement_target: 'InstancePlacementTargetPrototype' = None,
                 profile: 'InstanceProfileIdentity' = None,
                 user_data: str = None,
                 volume_attachments: List[
                     'VolumeAttachmentPrototypeInstanceContext'] = None,
                 vpc: 'VPCIdentity' = None,
                 boot_volume_attachment:
                 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
                 image: 'ImageIdentity' = None,
                 primary_network_interface: 'NetworkInterfacePrototype' = None,
                 zone: 'ZoneIdentity' = None) -> None:
        """
        Initialize a InstanceTemplateInstanceBySourceTemplate object.

        :param datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The unique user-defined name for this instance template.
        :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 InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use 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.
        :param ImageIdentity image: (optional) The identity of the image to use
               when provisioning the virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: (optional)
               Primary network interface.
        :param ZoneIdentity zone: (optional) The zone this virtual server instance
               will reside in.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.keys = keys
        self.name = name
        self.network_interfaces = network_interfaces
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.primary_network_interface = primary_network_interface
        self.source_template = source_template
        self.zone = zone

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'InstanceTemplateInstanceBySourceTemplate':
        """Initialize a InstanceTemplateInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [
                NetworkInterfacePrototype.from_dict(x)
                for x in _dict.get('network_interfaces')
            ]
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        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 '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 '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 'primary_network_interface' in _dict:
            args[
                'primary_network_interface'] = NetworkInterfacePrototype.from_dict(
                    _dict.get('primary_network_interface'))
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError(
                'Required property \'source_template\' not present in InstanceTemplateInstanceBySourceTemplate JSON'
            )
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        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, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'id') and self.id is not None:
            _dict['id'] = self.id
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        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, 'resource_group') and self.resource_group is not None:
            _dict['resource_group'] = self.resource_group.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, '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, 'primary_network_interface'
                  ) and self.primary_network_interface is not None:
            _dict[
                'primary_network_interface'] = self.primary_network_interface.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()
        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 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 crn: The CRN for this key.
    :attr KeyReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str fingerprint: The fingerprint for this key.  The value is returned
          base64-encoded and prefixed with the hash algorithm (always `SHA256`).
    :attr str href: The URL for this key.
    :attr str id: The unique identifier for this key.
    :attr str name: The user-defined name for this key.
    """

    def __init__(self,
                 crn: str,
                 fingerprint: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'KeyReferenceDeleted' = None) -> None:
        """
        Initialize a KeyReferenceInstanceInitializationContextKeyReference object.

        :param str crn: The CRN 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 href: The URL for this key.
        :param str id: The unique identifier for this key.
        :param str name: The user-defined name for this key.
        :param KeyReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.fingerprint = fingerprint
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(
            cls, _dict: Dict
    ) -> 'KeyReferenceInstanceInitializationContextKeyReference':
        """Initialize a KeyReferenceInstanceInitializationContextKeyReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in KeyReferenceInstanceInitializationContextKeyReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = KeyReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError(
                'Required property \'fingerprint\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch(
        LoadBalancerListenerPolicyTargetPatch):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch.

    :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 LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch 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
    ) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch object from 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity(
        LoadBalancerListenerPolicyTargetPatch):
    """
    Identifies a load balancer pool by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById',
                'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype(
        LoadBalancerListenerPolicyTargetPrototype):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype.

    :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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype 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
    ) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype JSON'
            )
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        else:
            raise ValueError(
                'Required property \'url\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype object from 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity(
        LoadBalancerListenerPolicyTargetPrototype):
    """
    Identifies a load balancer pool by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById',
                'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
            ]))
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL(
        LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL.

    :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 LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL 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
    ) -> 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL':
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL 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 LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL JSON'
            )
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        else:
            raise ValueError(
                'Required property \'url\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL object from 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 LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetLoadBalancerPoolReference(
        LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerPoolReference.

    :attr LoadBalancerPoolReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The pool's canonical URL.
    :attr str id: The unique identifier for this load balancer pool.
    :attr str name: The user-defined name for this load balancer pool.
    """

    def __init__(self,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'LoadBalancerPoolReferenceDeleted' = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object.

        :param str href: The pool's canonical URL.
        :param str id: The unique identifier for this load balancer pool.
        :param str name: The user-defined name for this load balancer pool.
        :param LoadBalancerPoolReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference':
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerPoolReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference'
    ) -> 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 crn: The CRN for this virtual server instance.
    :attr InstanceReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr str name: The user-defined name for this virtual server instance (and
          default system hostname).
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'InstanceReferenceDeleted' = None) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetInstanceReference object.

        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param str name: The user-defined name for this virtual server instance
               (and default system hostname).
        :param InstanceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'LoadBalancerPoolMemberTargetInstanceReference':
        """Initialize a LoadBalancerPoolMemberTargetInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = InstanceReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 globally unique name for this load balancer profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a LoadBalancerProfileIdentityByName object.

        :param str name: The globally unique 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 LoadBalancerProfileSecurityGroupsSupportedDependent(
        LoadBalancerProfileSecurityGroupsSupported):
    """
    The security group support for a load balancer with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(self, type: str) -> None:
        """
        Initialize a LoadBalancerProfileSecurityGroupsSupportedDependent 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
    ) -> 'LoadBalancerProfileSecurityGroupsSupportedDependent':
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerProfileSecurityGroupsSupportedDependent JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedDependent object from 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 LoadBalancerProfileSecurityGroupsSupportedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'LoadBalancerProfileSecurityGroupsSupportedDependent'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'LoadBalancerProfileSecurityGroupsSupportedDependent'
    ) -> 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 LoadBalancerProfileSecurityGroupsSupportedFixed(
        LoadBalancerProfileSecurityGroupsSupported):
    """
    The security group support for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr bool value: The value for this profile field.
    """

    def __init__(self, type: str, value: bool) -> None:
        """
        Initialize a LoadBalancerProfileSecurityGroupsSupportedFixed object.

        :param str type: The type for this profile field.
        :param bool 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) -> 'LoadBalancerProfileSecurityGroupsSupportedFixed':
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError(
                'Required property \'type\' not present in LoadBalancerProfileSecurityGroupsSupportedFixed JSON'
            )
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError(
                'Required property \'value\' not present in LoadBalancerProfileSecurityGroupsSupportedFixed JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedFixed object from 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 LoadBalancerProfileSecurityGroupsSupportedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'LoadBalancerProfileSecurityGroupsSupportedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'LoadBalancerProfileSecurityGroupsSupportedFixed') -> 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 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 ResourceGroupIdentity resource_group: (optional)
    :attr VPCIdentity vpc: The VPC this network ACL is to be a part of.
    :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)
        :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.resource_group = resource_group
        self.vpc = vpc
        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 '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 NetworkACLPrototypeNetworkACLByRules JSON'
            )
        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, '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, '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 ResourceGroupIdentity resource_group: (optional)
    :attr VPCIdentity vpc: The VPC this network ACL is to be a part of.
    :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)
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.vpc = vpc
        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 '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 NetworkACLPrototypeNetworkACLBySourceNetworkACL JSON'
            )
        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, '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,
                '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 NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref(
        NetworkACLRuleBeforePatch):
    """
    NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref.

    :attr str href: The URL for this network ACL rule.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref 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
    ) -> 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref':
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object from 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 NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePatchNetworkACLRuleIdentityById(
        NetworkACLRuleBeforePatch):
    """
    NetworkACLRuleBeforePatchNetworkACLRuleIdentityById.

    :attr str id: The unique identifier for this network ACL rule.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityById 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
    ) -> 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById':
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleBeforePatchNetworkACLRuleIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object from 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 NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref(
        NetworkACLRuleBeforePrototype):
    """
    NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref.

    :attr str href: The URL for this network ACL rule.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref 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
    ) -> 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref':
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object from 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 NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById(
        NetworkACLRuleBeforePrototype):
    """
    NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById.

    :attr str id: The unique identifier for this network ACL rule.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById 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
    ) -> 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById':
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object from 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 NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleItemNetworkACLRuleProtocolAll(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolAll.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 source: The source 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,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 source: str,
                 protocol: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRuleItemNetworkACLRuleProtocolAll object.

        :param str action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 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 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.action = action
        self.before = before
        self.created_at = created_at
        self.destination = destination
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleItemNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' 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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'


class NetworkACLRuleItemNetworkACLRuleProtocolICMP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolICMP.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :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 str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to allow. If unspecified, all
          types are allowed by this rule.
    """

    def __init__(self,
                 action: str,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 source: str,
                 protocol: str,
                 *,
                 before: 'NetworkACLRuleReference' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRuleItemNetworkACLRuleProtocolICMP object.

        :param str action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 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 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.action = action
        self.before = before
        self.created_at = created_at
        self.destination = destination
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.code = code
        self.protocol = protocol
        self.type = type

    @classmethod
    def from_dict(
            cls, _dict: Dict) -> 'NetworkACLRuleItemNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' 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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ICMP = 'icmp'


class NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :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 str protocol: The protocol to enforce.
    :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,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 source: str,
                 protocol: 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 action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 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 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.action = action
        self.before = before
        self.created_at = created_at
        self.destination = destination
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        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 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' 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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 '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 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        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, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll(
        NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll.

    :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 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 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.action = action
        self.destination = destination
        self.direction = direction
        self.name = name
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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'


class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP(
        NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP.

    :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 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 source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :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 str protocol: The protocol to enforce.
    :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.action = action
        self.destination = destination
        self.direction = direction
        self.name = name
        self.source = source
        self.code = code
        self.protocol = protocol
        self.type = type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMP JSON'
            )
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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.
        """
        ICMP = 'icmp'


class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP(
        NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP.

    :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 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 source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :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 str protocol: The protocol to enforce.
    :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.action = action
        self.destination = destination
        self.direction = direction
        self.name = name
        self.source = source
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        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 '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 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' 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 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDP JSON'
            )
        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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        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, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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.
        """
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRulePrototypeNetworkACLRuleProtocolAll(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolAll.

    :attr str action: Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePrototype before: (optional)
    :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 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 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,
                 *,
                 before: 'NetworkACLRuleBeforePrototype' = None,
                 name: str = 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 NetworkACLRuleBeforePrototype before: (optional)
        :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.action = action
        self.before = before
        self.destination = destination
        self.direction = direction
        self.name = name
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAll JSON'
            )
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        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'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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') 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, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 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'


class NetworkACLRulePrototypeNetworkACLRuleProtocolICMP(NetworkACLRulePrototype
                                                       ):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolICMP.

    :attr str action: Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePrototype before: (optional)
    :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 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 source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :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 str protocol: The protocol to enforce.
    :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,
                 *,
                 before: 'NetworkACLRuleBeforePrototype' = None,
                 name: str = 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 NetworkACLRuleBeforePrototype before: (optional)
        :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.action = action
        self.before = before
        self.destination = destination
        self.direction = direction
        self.name = name
        self.source = source
        self.code = code
        self.protocol = protocol
        self.type = type

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMP JSON'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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') 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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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.
        """
        ICMP = 'icmp'


class NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP(
        NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP.

    :attr str action: Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePrototype before: (optional)
    :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 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 source: The source IP address or CIDR block.  The CIDR block
          `0.0.0.0/0` applies to all addresses.
    :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 str protocol: The protocol to enforce.
    :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,
                 *,
                 before: 'NetworkACLRuleBeforePrototype' = None,
                 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 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 NetworkACLRuleBeforePrototype before: (optional)
        :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.action = action
        self.before = before
        self.destination = destination
        self.direction = direction
        self.name = name
        self.source = source
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        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 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        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 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError(
                'Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP 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 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDP JSON'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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') 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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        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, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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.
        """
        TCP = 'tcp'
        UDP = 'udp'


class NetworkACLRuleNetworkACLRuleProtocolAll(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolAll.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 source: The source 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,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 source: str,
                 protocol: str,
                 *,
                 before: 'NetworkACLRuleReference' = None) -> None:
        """
        Initialize a NetworkACLRuleNetworkACLRuleProtocolAll object.

        :param str action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 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 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.action = action
        self.before = before
        self.created_at = created_at
        self.destination = destination
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' 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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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 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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ALL = 'all'


class NetworkACLRuleNetworkACLRuleProtocolICMP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolICMP.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :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 str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to allow. If unspecified, all
          types are allowed by this rule.
    """

    def __init__(self,
                 action: str,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 source: str,
                 protocol: str,
                 *,
                 before: 'NetworkACLRuleReference' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRuleNetworkACLRuleProtocolICMP object.

        :param str action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 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 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.action = action
        self.before = before
        self.created_at = created_at
        self.destination = destination
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.code = code
        self.protocol = protocol
        self.type = type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'NetworkACLRuleNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' 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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        ICMP = 'icmp'


class NetworkACLRuleNetworkACLRuleProtocolTCPUDP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolTCPUDP.

    :attr str action: Whether to allow or deny matching traffic.
    :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 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 href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str ip_version: The IP version for this 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 source: The source CIDR block. The CIDR block `0.0.0.0/0` applies to
          all addresses.
    :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 str protocol: The protocol to enforce.
    :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,
                 created_at: datetime,
                 destination: str,
                 direction: str,
                 href: str,
                 id: str,
                 ip_version: str,
                 name: str,
                 source: str,
                 protocol: 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 action: Whether to allow or deny matching traffic.
        :param datetime created_at: The date and time that the rule was created.
        :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 href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str ip_version: The IP version for this 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 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 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.action = action
        self.before = before
        self.created_at = created_at
        self.destination = destination
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        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 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError(
                'Required property \'action\' 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 '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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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 '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 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON'
            )
        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, 'action') and self.action is not None:
            _dict['action'] = self.action
        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, '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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        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, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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 IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """
        IPV4 = 'ipv4'
        IPV6 = 'ipv6'

    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """
        TCP = 'tcp'
        UDP = 'udp'


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 globally unique name for this operating system.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a OperatingSystemIdentityByName object.

        :param str name: The globally unique name for this 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 PublicGatewayFloatingIPPrototypeFloatingIPIdentity(
        PublicGatewayFloatingIPPrototype):
    """
    Identifies a floating IP by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById',
                'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN',
                'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref',
                'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress'
            ]))
        raise Exception(msg)


class PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext(
        PublicGatewayFloatingIPPrototype):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext.

    :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 PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext 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
    ) -> 'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext 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 PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext object from 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 PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext'
    ) -> 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 ReservedIPTargetPrototypeEndpointGatewayIdentity(ReservedIPTargetPrototype
                                                      ):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentity.

    """

    def __init__(self) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById',
                'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN',
                'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref'
            ]))
        raise Exception(msg)


class ReservedIPTargetEndpointGatewayReference(ReservedIPTarget):
    """
    ReservedIPTargetEndpointGatewayReference.

    :attr str crn: The CRN for this endpoint gateway.
    :attr EndpointGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The URL for this endpoint gateway.
    :attr str id: The unique identifier for this endpoint gateway.
    :attr str name: The unique user-defined name for this endpoint gateway.
    :attr str resource_type: The type of resource referenced.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 *,
                 deleted: 'EndpointGatewayReferenceDeleted' = None) -> None:
        """
        Initialize a ReservedIPTargetEndpointGatewayReference object.

        :param str crn: The CRN for this endpoint gateway.
        :param str href: The URL for this endpoint gateway.
        :param str id: The unique identifier for this endpoint gateway.
        :param str name: The unique user-defined name for this endpoint gateway.
        :param str resource_type: The type of resource referenced.
        :param EndpointGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'ReservedIPTargetEndpointGatewayReference':
        """Initialize a ReservedIPTargetEndpointGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in ReservedIPTargetEndpointGatewayReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = EndpointGatewayReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPTargetEndpointGatewayReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ReservedIPTargetEndpointGatewayReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in ReservedIPTargetEndpointGatewayReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in ReservedIPTargetEndpointGatewayReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetEndpointGatewayReference object from 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
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 ReservedIPTargetEndpointGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetEndpointGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetEndpointGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """
        ENDPOINT_GATEWAY = 'endpoint_gateway'


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.

    :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 RouteNextHopPrototypeVPNGatewayConnectionIdentity(RouteNextHopPrototype):
    """
    Identifies a VPN gateway connection by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById',
                'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref'
            ]))
        raise Exception(msg)


class RouteNextHopVPNGatewayConnectionReference(RouteNextHop):
    """
    RouteNextHopVPNGatewayConnectionReference.

    :attr VPNGatewayConnectionReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :attr str name: The user-defined name for this VPN connection.
    :attr str resource_type: The resource type.
    """

    def __init__(
            self,
            href: str,
            id: str,
            name: str,
            resource_type: str,
            *,
            deleted: 'VPNGatewayConnectionReferenceDeleted' = None) -> None:
        """
        Initialize a RouteNextHopVPNGatewayConnectionReference object.

        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str name: The user-defined name for this VPN connection.
        :param str resource_type: The resource type.
        :param VPNGatewayConnectionReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'RouteNextHopVPNGatewayConnectionReference':
        """Initialize a RouteNextHopVPNGatewayConnectionReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = VPNGatewayConnectionReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RouteNextHopVPNGatewayConnectionReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in RouteNextHopVPNGatewayConnectionReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in RouteNextHopVPNGatewayConnectionReference JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in RouteNextHopVPNGatewayConnectionReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopVPNGatewayConnectionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 RouteNextHopVPNGatewayConnectionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'RouteNextHopVPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'RouteNextHopVPNGatewayConnectionReference') -> 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 RoutingTableIdentityByHref(RoutingTableIdentity):
    """
    RoutingTableIdentityByHref.

    :attr str href: The URL for this routing table.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a RoutingTableIdentityByHref object.

        :param str href: The URL for this routing table.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableIdentityByHref':
        """Initialize a RoutingTableIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RoutingTableIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableIdentityByHref object from 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 RoutingTableIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableIdentityById(RoutingTableIdentity):
    """
    RoutingTableIdentityById.

    :attr str id: The unique identifier for this routing table.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a RoutingTableIdentityById object.

        :param str id: The unique identifier for this routing table.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableIdentityById':
        """Initialize a RoutingTableIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in RoutingTableIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableIdentityById object from 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 RoutingTableIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableIdentityById') -> 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 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 SecurityGroupRuleRemotePrototype remote: (optional)
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 direction: str,
                 protocol: str,
                 *,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemotePrototype' = None) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str protocol: The protocol to enforce.
        :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 SecurityGroupRuleRemotePrototype remote: (optional)
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.ip_version = ip_version
        self.remote = remote
        self.protocol = protocol

    @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 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll JSON'
            )
        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, '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, '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 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'


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 SecurityGroupRuleRemotePrototype remote: (optional)
    :attr int code: (optional) The ICMP traffic code to allow.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to allow.
    """

    def __init__(self,
                 direction: str,
                 protocol: str,
                 *,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemotePrototype' = 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 protocol: The protocol to enforce.
        :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 SecurityGroupRuleRemotePrototype remote: (optional)
        :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.remote = remote
        self.code = code
        self.protocol = protocol
        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 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP JSON'
            )
        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, '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, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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.
        """
        ICMP = 'icmp'


class SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP(
        SecurityGroupRulePrototype):
    """
    If `protocol` is either `tcp` or `udp`, then the rule may also contain `port_min` and
    `port_max`. Either both must 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 SecurityGroupRuleRemotePrototype remote: (optional)
    :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.
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 direction: str,
                 protocol: str,
                 *,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemotePrototype' = 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 protocol: The protocol to enforce.
        :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 SecurityGroupRuleRemotePrototype remote: (optional)
        :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.remote = remote
        self.port_max = port_max
        self.port_min = port_min
        self.protocol = protocol

    @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 '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')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP JSON'
            )
        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, '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
        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 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.
        """
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupRuleRemotePatchCIDR(SecurityGroupRuleRemotePatch):
    """
    SecurityGroupRuleRemotePatchCIDR.

    :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 SecurityGroupRuleRemotePatchCIDR 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) -> 'SecurityGroupRuleRemotePatchCIDR':
        """Initialize a SecurityGroupRuleRemotePatchCIDR 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 SecurityGroupRuleRemotePatchCIDR JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchCIDR object from 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 SecurityGroupRuleRemotePatchCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePatchCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePatchCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchIP(SecurityGroupRuleRemotePatch):
    """
    SecurityGroupRuleRemotePatchIP.

    :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 SecurityGroupRuleRemotePatchIP 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) -> 'SecurityGroupRuleRemotePatchIP':
        """Initialize a SecurityGroupRuleRemotePatchIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in SecurityGroupRuleRemotePatchIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchIP object from 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 SecurityGroupRuleRemotePatchIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePatchIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePatchIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchSecurityGroupIdentity(
        SecurityGroupRuleRemotePatch):
    """
    Identifies a security group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById',
                'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN',
                'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref'
            ]))
        raise Exception(msg)


class SecurityGroupRuleRemotePrototypeCIDR(SecurityGroupRuleRemotePrototype):
    """
    SecurityGroupRuleRemotePrototypeCIDR.

    :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 SecurityGroupRuleRemotePrototypeCIDR 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) -> 'SecurityGroupRuleRemotePrototypeCIDR':
        """Initialize a SecurityGroupRuleRemotePrototypeCIDR 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 SecurityGroupRuleRemotePrototypeCIDR JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeCIDR object from 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 SecurityGroupRuleRemotePrototypeCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePrototypeCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePrototypeCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeIP(SecurityGroupRuleRemotePrototype):
    """
    SecurityGroupRuleRemotePrototypeIP.

    :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 SecurityGroupRuleRemotePrototypeIP 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) -> 'SecurityGroupRuleRemotePrototypeIP':
        """Initialize a SecurityGroupRuleRemotePrototypeIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in SecurityGroupRuleRemotePrototypeIP JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeIP object from 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 SecurityGroupRuleRemotePrototypeIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePrototypeIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePrototypeIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeSecurityGroupIdentity(
        SecurityGroupRuleRemotePrototype):
    """
    Identifies a security group by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById',
                'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN',
                'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref'
            ]))
        raise Exception(msg)


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 crn: The security group's CRN.
    :attr SecurityGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :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,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'SecurityGroupReferenceDeleted' = None) -> None:
        """
        Initialize a SecurityGroupRuleRemoteSecurityGroupReference object.

        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :param str name: The user-defined name for this security group. Names must
               be unique within the VPC the security group resides in.
        :param SecurityGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleRemoteSecurityGroupReference':
        """Initialize a SecurityGroupRuleRemoteSecurityGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = SecurityGroupReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' 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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _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 direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :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 SecurityGroupRuleRemote remote:
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 direction: str,
                 href: str,
                 id: str,
                 remote: 'SecurityGroupRuleRemote',
                 protocol: str,
                 *,
                 ip_version: str = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param SecurityGroupRuleRemote remote:
        :param str protocol: The protocol to enforce.
        :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.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.remote = remote
        self.protocol = protocol

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolAll':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError(
                'Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON'
            )
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' 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, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        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, '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 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'


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 direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :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 SecurityGroupRuleRemote remote:
    :attr int code: (optional) The ICMP traffic code to allow.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to allow.
    """

    def __init__(self,
                 direction: str,
                 href: str,
                 id: str,
                 remote: 'SecurityGroupRuleRemote',
                 protocol: str,
                 *,
                 ip_version: str = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param SecurityGroupRuleRemote remote:
        :param str protocol: The protocol to enforce.
        :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 type: (optional) The ICMP traffic type to allow.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.remote = remote
        self.code = code
        self.protocol = protocol
        self.type = type

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolICMP':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON'
            )
        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, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        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, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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.
        """
        ICMP = 'icmp'


class SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP(SecurityGroupRule):
    """
    If `protocol` is either `tcp` or `udp`, then the rule may also contain `port_min` and
    `port_max`. Either both must 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 href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :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 SecurityGroupRuleRemote remote:
    :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.
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 direction: str,
                 href: str,
                 id: str,
                 remote: 'SecurityGroupRuleRemote',
                 protocol: str,
                 *,
                 ip_version: str = None,
                 port_max: int = None,
                 port_min: int = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param SecurityGroupRuleRemote remote:
        :param str protocol: The protocol to enforce.
        :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 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.href = href
        self.id = id
        self.ip_version = ip_version
        self.remote = remote
        self.port_max = port_max
        self.port_min = port_min
        self.protocol = protocol

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError(
                'Required property \'direction\' 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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON'
            )
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON'
            )
        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, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        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
        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 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.
        """
        TCP = 'tcp'
        UDP = 'udp'


class SecurityGroupTargetReferenceLoadBalancerReference(
        SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceLoadBalancerReference.

    :attr str crn: The load balancer's CRN.
    :attr LoadBalancerReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted and provides
          some supplementary information.
    :attr str href: The load balancer's canonical URL.
    :attr str id: The unique identifier for this load balancer.
    :attr str name: The unique user-defined name for this load balancer.
    """

    def __init__(self,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 *,
                 deleted: 'LoadBalancerReferenceDeleted' = None) -> None:
        """
        Initialize a SecurityGroupTargetReferenceLoadBalancerReference object.

        :param str crn: The load balancer's CRN.
        :param str href: The load balancer's canonical URL.
        :param str id: The unique identifier for this load balancer.
        :param str name: The unique user-defined name for this load balancer.
        :param LoadBalancerReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'SecurityGroupTargetReferenceLoadBalancerReference':
        """Initialize a SecurityGroupTargetReferenceLoadBalancerReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON'
            )
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerReferenceDeleted.from_dict(
                _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceLoadBalancerReference object from 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
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetReferenceLoadBalancerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'SecurityGroupTargetReferenceLoadBalancerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'SecurityGroupTargetReferenceLoadBalancerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext(
        SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext.

    :attr NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted and
          provides
          some supplementary information.
    :attr str href: The URL for this network interface.
    :attr str id: The unique identifier 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,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'NetworkInterfaceReferenceTargetContextDeleted' = None
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this network interface.
        :param str id: The unique identifier for this network interface.
        :param str name: The user-defined name for this network interface.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted
               and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext':
        """Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args[
                'deleted'] = NetworkInterfaceReferenceTargetContextDeleted.from_dict(
                    _dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, '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 SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext'
    ) -> 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 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 ip_version: (optional) The IP version(s) to support for this subnet.
    :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. If unspecified, the default network ACL for the VPC is used.
    :attr PublicGatewayIdentity public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet. If unspecified, the default routing table for the VPC is used.
          The routing table properties `route_direct_link_ingress`,
          `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be `false`.
    :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 `/9` (8,388,608
          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 this subnet will reside in.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 ipv4_cidr_block: str,
                 *,
                 ip_version: str = None,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 routing_table: 'RoutingTableIdentity' = 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 `/9`
               (8,388,608 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 ip_version: (optional) The IP version(s) to support for this
               subnet.
        :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. If unspecified, the default network ACL for the VPC is
               used.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        :param ResourceGroupIdentity resource_group: (optional)
        :param RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet. If unspecified, the default routing table for the VPC
               is used. The routing table properties `route_direct_link_ingress`,
               `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be
               `false`.
        :param ZoneIdentity zone: (optional) The zone this subnet will reside in.
        """
        # pylint: disable=super-init-not-called
        self.ip_version = ip_version
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.resource_group = resource_group
        self.routing_table = routing_table
        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 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'routing_table' in _dict:
            args['routing_table'] = _dict.get('routing_table')
        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, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        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, '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, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.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 ip_version: (optional) The IP version(s) to support for this subnet.
    :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. If unspecified, the default network ACL for the VPC is used.
    :attr PublicGatewayIdentity public_gateway: (optional) The public gateway to
          handle internet bound traffic for this subnet.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet. If unspecified, the default routing table for the VPC is used.
          The routing table properties `route_direct_link_ingress`,
          `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be `false`.
    :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 this subnet will reside in.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 total_ipv4_address_count: int,
                 zone: 'ZoneIdentity',
                 *,
                 ip_version: str = None,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 routing_table: 'RoutingTableIdentity' = 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 this subnet will reside in.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :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. If unspecified, the default network ACL for the VPC is
               used.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        :param ResourceGroupIdentity resource_group: (optional)
        :param RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet. If unspecified, the default routing table for the VPC
               is used. The routing table properties `route_direct_link_ingress`,
               `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be
               `false`.
        """
        # pylint: disable=super-init-not-called
        self.ip_version = ip_version
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.resource_group = resource_group
        self.routing_table = routing_table
        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 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'routing_table' in _dict:
            args['routing_table'] = _dict.get('routing_table')
        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, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        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, '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, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.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 VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch(
        VPNGatewayConnectionPatch):
    """
    VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
    :attr IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr str name: (optional) The user-defined name for this VPN gateway
          connection.
    :attr str peer_address: (optional) The IP address of the peer VPN gateway.
    :attr str psk: (optional) The preshared key.
    :attr str routing_protocol: (optional) Routing protocols are disabled for this
          VPN gateway connection.
    """

    def __init__(self,
                 *,
                 admin_state_up: bool = None,
                 dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
                 ike_policy: 'IKEPolicyIdentity' = None,
                 ipsec_policy: 'IPsecPolicyIdentity' = None,
                 name: str = None,
                 peer_address: str = None,
                 psk: str = None,
                 routing_protocol: str = None) -> None:
        """
        Initialize a VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object.

        :param bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
        :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 str name: (optional) The user-defined name for this VPN gateway
               connection.
        :param str peer_address: (optional) The IP address of the peer VPN gateway.
        :param str psk: (optional) The preshared key.
        :param str routing_protocol: (optional) Routing protocols are disabled for
               this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.dead_peer_detection = dead_peer_detection
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.routing_protocol = routing_protocol

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch':
        """Initialize a VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object from a json dictionary."""
        args = {}
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        if 'dead_peer_detection' in _dict:
            args[
                'dead_peer_detection'] = VPNGatewayConnectionDPDPrototype.from_dict(
                    _dict.get('dead_peer_detection'))
        if 'ike_policy' in _dict:
            args['ike_policy'] = _dict.get('ike_policy')
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = _dict.get('ipsec_policy')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        if 'routing_protocol' in _dict:
            args['routing_protocol'] = _dict.get('routing_protocol')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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,
                '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:
            if isinstance(self.ike_policy, dict):
                _dict['ike_policy'] = self.ike_policy
            else:
                _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            if isinstance(self.ipsec_policy, dict):
                _dict['ipsec_policy'] = self.ipsec_policy
            else:
                _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'routing_protocol') and self.routing_protocol is not None:
            _dict['routing_protocol'] = self.routing_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 VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """
        NONE = 'none'


class VPNGatewayConnectionPolicyMode(VPNGatewayConnection):
    """
    VPNGatewayConnectionPolicyMode.

    :attr bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :attr str authentication_mode: The authentication mode. Only `psk` is currently
          supported.
    :attr datetime created_at: The date and time that this VPN gateway connection
          was created.
    :attr VPNGatewayConnectionDPD dead_peer_detection:
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :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.
    :attr str mode: The mode of the VPN gateway.
    :attr str name: The user-defined name for this VPN gateway connection.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The preshared key.
    :attr str resource_type: The resource type.
    :attr str status: The status of a VPN gateway connection.
    :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.
    """

    def __init__(self,
                 admin_state_up: bool,
                 authentication_mode: str,
                 created_at: datetime,
                 dead_peer_detection: 'VPNGatewayConnectionDPD',
                 href: str,
                 id: str,
                 mode: str,
                 name: str,
                 peer_address: str,
                 psk: str,
                 resource_type: str,
                 status: str,
                 local_cidrs: List[str],
                 peer_cidrs: List[str],
                 *,
                 ike_policy: 'IKEPolicyReference' = None,
                 ipsec_policy: 'IPsecPolicyReference' = None) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyMode object.

        :param bool admin_state_up: If set to false, the VPN gateway connection is
               shut down.
        :param str authentication_mode: The authentication mode. Only `psk` is
               currently supported.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection:
        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
        :param str name: The user-defined name for this VPN gateway connection.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The preshared key.
        :param str resource_type: The resource type.
        :param str status: The status of a VPN gateway connection.
        :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 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.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.authentication_mode = authentication_mode
        self.created_at = created_at
        self.dead_peer_detection = dead_peer_detection
        self.href = href
        self.id = id
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.mode = mode
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.resource_type = resource_type
        self.status = status
        self.local_cidrs = local_cidrs
        self.peer_cidrs = peer_cidrs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPolicyMode':
        """Initialize a VPNGatewayConnectionPolicyMode object from a json dictionary."""
        args = {}
        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 VPNGatewayConnectionPolicyMode JSON'
            )
        if 'authentication_mode' in _dict:
            args['authentication_mode'] = _dict.get('authentication_mode')
        else:
            raise ValueError(
                'Required property \'authentication_mode\' not present in VPNGatewayConnectionPolicyMode 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 VPNGatewayConnectionPolicyMode 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 VPNGatewayConnectionPolicyMode JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGatewayConnectionPolicyMode 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'))
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError(
                'Required property \'mode\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError(
                'Required property \'peer_address\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError(
                'Required property \'psk\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'local_cidrs' in _dict:
            args['local_cidrs'] = _dict.get('local_cidrs')
        else:
            raise ValueError(
                'Required property \'local_cidrs\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        if 'peer_cidrs' in _dict:
            args['peer_cidrs'] = _dict.get('peer_cidrs')
        else:
            raise ValueError(
                'Required property \'peer_cidrs\' not present in VPNGatewayConnectionPolicyMode JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPolicyMode object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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,
                'authentication_mode') and self.authentication_mode is not None:
            _dict['authentication_mode'] = self.authentication_mode
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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()
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.mode
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPolicyMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPolicyMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPolicyMode') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode. Only `psk` is currently supported.
        """
        PSK = 'psk'

    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        """
        POLICY = 'policy'
        ROUTE = 'route'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'

    class StatusEnum(str, Enum):
        """
        The status of a VPN gateway connection.
        """
        DOWN = 'down'
        UP = 'up'


class VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype(
        VPNGatewayConnectionPrototype):
    """
    VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
    :attr IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr str name: (optional) The user-defined name for this VPN gateway
          connection.
    :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.
    """

    def __init__(self,
                 peer_address: str,
                 psk: str,
                 local_cidrs: List[str],
                 peer_cidrs: List[str],
                 *,
                 admin_state_up: bool = None,
                 dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
                 ike_policy: 'IKEPolicyIdentity' = None,
                 ipsec_policy: 'IPsecPolicyIdentity' = None,
                 name: str = None) -> None:
        """
        Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object.

        :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 bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
        :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 str name: (optional) The user-defined name for this VPN gateway
               connection.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.dead_peer_detection = dead_peer_detection
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.local_cidrs = local_cidrs
        self.peer_cidrs = peer_cidrs

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype':
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object from a json dictionary."""
        args = {}
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        if 'dead_peer_detection' in _dict:
            args[
                'dead_peer_detection'] = VPNGatewayConnectionDPDPrototype.from_dict(
                    _dict.get('dead_peer_detection'))
        if 'ike_policy' in _dict:
            args['ike_policy'] = _dict.get('ike_policy')
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = _dict.get('ipsec_policy')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError(
                'Required property \'peer_address\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype JSON'
            )
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError(
                'Required property \'psk\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype JSON'
            )
        if 'local_cidrs' in _dict:
            args['local_cidrs'] = _dict.get('local_cidrs')
        else:
            raise ValueError(
                'Required property \'local_cidrs\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype JSON'
            )
        if 'peer_cidrs' in _dict:
            args['peer_cidrs'] = _dict.get('peer_cidrs')
        else:
            raise ValueError(
                'Required property \'peer_cidrs\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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,
                '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:
            if isinstance(self.ike_policy, dict):
                _dict['ike_policy'] = self.ike_policy
            else:
                _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            if isinstance(self.ipsec_policy, dict):
                _dict['ipsec_policy'] = self.ipsec_policy
            else:
                _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype(
        VPNGatewayConnectionPrototype):
    """
    VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
    :attr IKEPolicyIdentity ike_policy: (optional) Optional IKE policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr IPsecPolicyIdentity ipsec_policy: (optional) Optional IPsec policy
          configuration. The absence of a policy indicates autonegotiation.
    :attr str name: (optional) The user-defined name for this VPN gateway
          connection.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The preshared key.
    :attr str routing_protocol: (optional) Routing protocols are disabled for this
          VPN gateway connection.
    """

    def __init__(self,
                 peer_address: str,
                 psk: str,
                 *,
                 admin_state_up: bool = None,
                 dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
                 ike_policy: 'IKEPolicyIdentity' = None,
                 ipsec_policy: 'IPsecPolicyIdentity' = None,
                 name: str = None,
                 routing_protocol: str = None) -> None:
        """
        Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object.

        :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 gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
        :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 str name: (optional) The user-defined name for this VPN gateway
               connection.
        :param str routing_protocol: (optional) Routing protocols are disabled for
               this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.dead_peer_detection = dead_peer_detection
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.routing_protocol = routing_protocol

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype':
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object from a json dictionary."""
        args = {}
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        if 'dead_peer_detection' in _dict:
            args[
                'dead_peer_detection'] = VPNGatewayConnectionDPDPrototype.from_dict(
                    _dict.get('dead_peer_detection'))
        if 'ike_policy' in _dict:
            args['ike_policy'] = _dict.get('ike_policy')
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = _dict.get('ipsec_policy')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError(
                'Required property \'peer_address\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype JSON'
            )
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError(
                'Required property \'psk\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype JSON'
            )
        if 'routing_protocol' in _dict:
            args['routing_protocol'] = _dict.get('routing_protocol')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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,
                '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:
            if isinstance(self.ike_policy, dict):
                _dict['ike_policy'] = self.ike_policy
            else:
                _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            if isinstance(self.ipsec_policy, dict):
                _dict['ipsec_policy'] = self.ipsec_policy
            else:
                _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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,
                   'routing_protocol') and self.routing_protocol is not None:
            _dict['routing_protocol'] = self.routing_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 VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """
        NONE = 'none'


class VPNGatewayConnectionStaticRouteMode(VPNGatewayConnection):
    """
    VPNGatewayConnectionStaticRouteMode.

    :attr bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :attr str authentication_mode: The authentication mode. Only `psk` is currently
          supported.
    :attr datetime created_at: The date and time that this VPN gateway connection
          was created.
    :attr VPNGatewayConnectionDPD dead_peer_detection:
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :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.
    :attr str mode: The mode of the VPN gateway.
    :attr str name: The user-defined name for this VPN gateway connection.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The preshared key.
    :attr str resource_type: The resource type.
    :attr str status: The status of a VPN gateway connection.
    :attr str routing_protocol: Routing protocols are disabled for this VPN gateway
          connection.
    :attr List[VPNGatewayConnectionStaticRouteModeTunnel] tunnels: The VPN tunnel
          configuration for this VPN gateway connection (in static route mode).
    """

    def __init__(self,
                 admin_state_up: bool,
                 authentication_mode: str,
                 created_at: datetime,
                 dead_peer_detection: 'VPNGatewayConnectionDPD',
                 href: str,
                 id: str,
                 mode: str,
                 name: str,
                 peer_address: str,
                 psk: str,
                 resource_type: str,
                 status: str,
                 routing_protocol: str,
                 tunnels: List['VPNGatewayConnectionStaticRouteModeTunnel'],
                 *,
                 ike_policy: 'IKEPolicyReference' = None,
                 ipsec_policy: 'IPsecPolicyReference' = None) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteMode object.

        :param bool admin_state_up: If set to false, the VPN gateway connection is
               shut down.
        :param str authentication_mode: The authentication mode. Only `psk` is
               currently supported.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection:
        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
        :param str name: The user-defined name for this VPN gateway connection.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The preshared key.
        :param str resource_type: The resource type.
        :param str status: The status of a VPN gateway connection.
        :param str routing_protocol: Routing protocols are disabled for this VPN
               gateway connection.
        :param List[VPNGatewayConnectionStaticRouteModeTunnel] tunnels: The VPN
               tunnel configuration for this VPN gateway connection (in static route
               mode).
        :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.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.authentication_mode = authentication_mode
        self.created_at = created_at
        self.dead_peer_detection = dead_peer_detection
        self.href = href
        self.id = id
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.mode = mode
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.resource_type = resource_type
        self.status = status
        self.routing_protocol = routing_protocol
        self.tunnels = tunnels

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteMode':
        """Initialize a VPNGatewayConnectionStaticRouteMode object from a json dictionary."""
        args = {}
        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 VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'authentication_mode' in _dict:
            args['authentication_mode'] = _dict.get('authentication_mode')
        else:
            raise ValueError(
                'Required property \'authentication_mode\' not present in VPNGatewayConnectionStaticRouteMode 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 VPNGatewayConnectionStaticRouteMode 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 VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGatewayConnectionStaticRouteMode 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'))
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError(
                'Required property \'mode\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError(
                'Required property \'peer_address\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError(
                'Required property \'psk\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'routing_protocol' in _dict:
            args['routing_protocol'] = _dict.get('routing_protocol')
        else:
            raise ValueError(
                'Required property \'routing_protocol\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        if 'tunnels' in _dict:
            args['tunnels'] = [
                VPNGatewayConnectionStaticRouteModeTunnel.from_dict(x)
                for x in _dict.get('tunnels')
            ]
        else:
            raise ValueError(
                'Required property \'tunnels\' not present in VPNGatewayConnectionStaticRouteMode JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteMode object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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,
                'authentication_mode') and self.authentication_mode is not None:
            _dict['authentication_mode'] = self.authentication_mode
        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, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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()
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.mode
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self,
                   'routing_protocol') and self.routing_protocol is not None:
            _dict['routing_protocol'] = self.routing_protocol
        if hasattr(self, 'tunnels') and self.tunnels is not None:
            _dict['tunnels'] = [x.to_dict() for x in self.tunnels]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionStaticRouteMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteMode') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode. Only `psk` is currently supported.
        """
        PSK = 'psk'

    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        """
        POLICY = 'policy'
        ROUTE = 'route'

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'

    class StatusEnum(str, Enum):
        """
        The status of a VPN gateway connection.
        """
        DOWN = 'down'
        UP = 'up'

    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """
        NONE = 'none'


class VPNGatewayPolicyMode(VPNGateway):
    """
    VPNGatewayPolicyMode.

    :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 crn: The VPN gateway's CRN.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr List[VPNGatewayMember] members: Collection of VPN gateway members.
    :attr str name: The user-defined name for this VPN gateway.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr str resource_type: The resource type.
    :attr str status: The status of the VPN gateway.
    :attr SubnetReference subnet:
    :attr str mode: Policy mode VPN gateway.
    """

    def __init__(self, connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, crn: str, href: str, id: str,
                 members: List['VPNGatewayMember'], name: str,
                 resource_group: 'ResourceGroupReference', resource_type: str,
                 status: str, subnet: 'SubnetReference', mode: str) -> None:
        """
        Initialize a VPNGatewayPolicyMode object.

        :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 crn: The VPN gateway's CRN.
        :param str href: The VPN gateway's canonical URL.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayMember] members: Collection of VPN gateway members.
        :param str name: The user-defined name for this VPN gateway.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param str resource_type: The resource type.
        :param str status: The status of the VPN gateway.
        :param SubnetReference subnet:
        :param str mode: Policy mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.connections = connections
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.members = members
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.status = status
        self.subnet = subnet
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayPolicyMode':
        """Initialize a VPNGatewayPolicyMode object from a json dictionary."""
        args = {}
        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 VPNGatewayPolicyMode 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 VPNGatewayPolicyMode JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'members' in _dict:
            args['members'] = [
                VPNGatewayMember.from_dict(x) for x in _dict.get('members')
            ]
        else:
            raise ValueError(
                'Required property \'members\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGatewayPolicyMode 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 VPNGatewayPolicyMode JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError(
                'Required property \'subnet\' not present in VPNGatewayPolicyMode JSON'
            )
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError(
                'Required property \'mode\' not present in VPNGatewayPolicyMode JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPolicyMode object from 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]
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'members') and self.members is not None:
            _dict['members'] = [x.to_dict() for x in self.members]
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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, 'mode') and self.mode is not None:
            _dict['mode'] = self.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 VPNGatewayPolicyMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayPolicyMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayPolicyMode') -> 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 ModeEnum(str, Enum):
        """
        Policy mode VPN gateway.
        """
        POLICY = 'policy'


class VPNGatewayPrototypeVPNGatewayPolicyModePrototype(VPNGatewayPrototype):
    """
    VPNGatewayPrototypeVPNGatewayPolicyModePrototype.

    :attr str name: (optional) The user-defined name for this VPN gateway.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr SubnetIdentity subnet:
    :attr str mode: (optional) Policy mode VPN gateway.
    """

    def __init__(self,
                 subnet: 'SubnetIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 mode: str = None) -> None:
        """
        Initialize a VPNGatewayPrototypeVPNGatewayPolicyModePrototype object.

        :param SubnetIdentity subnet:
        :param str name: (optional) The user-defined name for this VPN gateway.
        :param ResourceGroupIdentity resource_group: (optional)
        :param str mode: (optional) Policy mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.subnet = subnet
        self.mode = mode

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype':
        """Initialize a VPNGatewayPrototypeVPNGatewayPolicyModePrototype 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 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError(
                'Required property \'subnet\' not present in VPNGatewayPrototypeVPNGatewayPolicyModePrototype JSON'
            )
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPrototypeVPNGatewayPolicyModePrototype object from 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, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.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 VPNGatewayPrototypeVPNGatewayPolicyModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        Policy mode VPN gateway.
        """
        POLICY = 'policy'


class VPNGatewayPrototypeVPNGatewayRouteModePrototype(VPNGatewayPrototype):
    """
    VPNGatewayPrototypeVPNGatewayRouteModePrototype.

    :attr str name: (optional) The user-defined name for this VPN gateway.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr SubnetIdentity subnet:
    :attr str mode: (optional) Route mode VPN gateway.
    """

    def __init__(self,
                 subnet: 'SubnetIdentity',
                 *,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 mode: str = None) -> None:
        """
        Initialize a VPNGatewayPrototypeVPNGatewayRouteModePrototype object.

        :param SubnetIdentity subnet:
        :param str name: (optional) The user-defined name for this VPN gateway.
        :param ResourceGroupIdentity resource_group: (optional)
        :param str mode: (optional) Route mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.subnet = subnet
        self.mode = mode

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'VPNGatewayPrototypeVPNGatewayRouteModePrototype':
        """Initialize a VPNGatewayPrototypeVPNGatewayRouteModePrototype 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 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError(
                'Required property \'subnet\' not present in VPNGatewayPrototypeVPNGatewayRouteModePrototype JSON'
            )
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPrototypeVPNGatewayRouteModePrototype object from 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, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.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 VPNGatewayPrototypeVPNGatewayRouteModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'VPNGatewayPrototypeVPNGatewayRouteModePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'VPNGatewayPrototypeVPNGatewayRouteModePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        Route mode VPN gateway.
        """
        ROUTE = 'route'


class VPNGatewayRouteMode(VPNGateway):
    """
    VPNGatewayRouteMode.

    :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 crn: The VPN gateway's CRN.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr List[VPNGatewayMember] members: Collection of VPN gateway members.
    :attr str name: The user-defined name for this VPN gateway.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr str resource_type: The resource type.
    :attr str status: The status of the VPN gateway.
    :attr SubnetReference subnet:
    :attr str mode: Route mode VPN gateway.
    """

    def __init__(self, connections: List['VPNGatewayConnectionReference'],
                 created_at: datetime, crn: str, href: str, id: str,
                 members: List['VPNGatewayMember'], name: str,
                 resource_group: 'ResourceGroupReference', resource_type: str,
                 status: str, subnet: 'SubnetReference', mode: str) -> None:
        """
        Initialize a VPNGatewayRouteMode object.

        :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 crn: The VPN gateway's CRN.
        :param str href: The VPN gateway's canonical URL.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayMember] members: Collection of VPN gateway members.
        :param str name: The user-defined name for this VPN gateway.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param str resource_type: The resource type.
        :param str status: The status of the VPN gateway.
        :param SubnetReference subnet:
        :param str mode: Route mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.connections = connections
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.members = members
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.status = status
        self.subnet = subnet
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayRouteMode':
        """Initialize a VPNGatewayRouteMode object from a json dictionary."""
        args = {}
        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 VPNGatewayRouteMode 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 VPNGatewayRouteMode JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VPNGatewayRouteMode JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VPNGatewayRouteMode JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VPNGatewayRouteMode JSON'
            )
        if 'members' in _dict:
            args['members'] = [
                VPNGatewayMember.from_dict(x) for x in _dict.get('members')
            ]
        else:
            raise ValueError(
                'Required property \'members\' not present in VPNGatewayRouteMode JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in VPNGatewayRouteMode 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 VPNGatewayRouteMode JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in VPNGatewayRouteMode JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in VPNGatewayRouteMode JSON'
            )
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError(
                'Required property \'subnet\' not present in VPNGatewayRouteMode JSON'
            )
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError(
                'Required property \'mode\' not present in VPNGatewayRouteMode JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayRouteMode object from 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]
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        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, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'members') and self.members is not None:
            _dict['members'] = [x.to_dict() for x in self.members]
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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, 'mode') and self.mode is not None:
            _dict['mode'] = self.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 VPNGatewayRouteMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayRouteMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayRouteMode') -> 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 ModeEnum(str, Enum):
        """
        Route mode VPN gateway.
        """
        ROUTE = 'route'


class VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity(
        VolumeAttachmentVolumePrototypeInstanceContext):
    """
    Identifies a volume by a unique property.

    """

    def __init__(self) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById',
                'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN',
                'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref'
            ]))
        raise Exception(msg)


class VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext(
        VolumeAttachmentVolumePrototypeInstanceContext):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext.

    :attr int iops: (optional) The bandwidth for the volume.
    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 *,
                 iops: int = None,
                 name: str = None) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param int iops: (optional) The bandwidth for the volume.
        :param str name: (optional) The unique user-defined name for this volume.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity'
            ]))
        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 globally unique name for this volume profile.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a VolumeProfileIdentityByName object.

        :param str name: The globally unique 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 int iops: (optional) The bandwidth for the volume.
    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr ZoneIdentity zone: The zone this volume will reside in.
    :attr int capacity: The capacity of the volume in gigabytes. The specified
          minimum and maximum capacity values for creating or updating volumes may expand
          in the future.
    :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`.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 zone: 'ZoneIdentity',
                 capacity: int,
                 *,
                 iops: int = None,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None,
                 encryption_key: 'EncryptionKeyIdentity' = None) -> None:
        """
        Initialize a VolumePrototypeVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param ZoneIdentity zone: The zone this volume will reside in.
        :param int capacity: The capacity of the volume in gigabytes. 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.
        :param str name: (optional) The unique user-defined name for this volume.
        :param ResourceGroupIdentity resource_group: (optional)
        :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`.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.zone = zone
        self.capacity = capacity
        self.encryption_key = encryption_key

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeVolumeByCapacity':
        """Initialize a VolumePrototypeVolumeByCapacity object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        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 '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'
            )
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        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, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        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, '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
        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 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 globally unique name for this zone.
    """

    def __init__(self, name: str) -> None:
        """
        Initialize a ZoneIdentityByName object.

        :param str name: The globally unique 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 EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref(
        EndpointGatewayReservedIPReservedIPIdentity):
    """
    EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref.

    :attr str href: The URL for this reserved IP.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref object.

        :param str href: The URL for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref':
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref object from 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 EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById(
        EndpointGatewayReservedIPReservedIPIdentity):
    """
    EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById.

    :attr str id: The unique identifier for this reserved IP.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById object.

        :param str id: The unique identifier for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById':
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById object from 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 EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'EndpointGatewayReservedIPReservedIPIdentityReservedIPIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN(
        EndpointGatewayTargetPrototypeProviderCloudServiceIdentity):
    """
    EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN.

    :attr str resource_type: The type of target for this endpoint gateway.
    :attr str crn: The CRN for this provider cloud service, or the CRN for the
          user's instance of a provider cloud service.
    """

    def __init__(self, resource_type: str, crn: str) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object.

        :param str resource_type: The type of target for this endpoint gateway.
        :param str crn: The CRN for this provider cloud service, or the CRN for the
               user's instance of a provider cloud service.
        """
        # pylint: disable=super-init-not-called
        self.resource_type = resource_type
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN':
        """Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN JSON'
            )
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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 EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'


class EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName(
        EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity):
    """
    The name of this provider infrastructure service.

    :attr str resource_type: The type of target for this endpoint gateway.
    :attr str name: The name of a provider infrastructure service. Must be:
          - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
    """

    def __init__(self, resource_type: str, name: str) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object.

        :param str resource_type: The type of target for this endpoint gateway.
        :param str name: The name of a provider infrastructure service. Must be:
               - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
        """
        # pylint: disable=super-init-not-called
        self.resource_type = resource_type
        self.name = name

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName':
        """Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object from a json dictionary."""
        args = {}
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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 EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN(
        FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN.

    :attr str crn: The CRN for this virtual server instance.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN 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
    ) -> 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from 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 FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref(
        FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref.

    :attr str href: The URL for this virtual server instance.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref 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
    ) -> 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object from 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 FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById(
        FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById.

    :attr str id: The unique identifier for this virtual server instance.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById 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
    ) -> 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object from 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 FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(
        FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this network interface.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref 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
    ) -> 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from 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 FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById(
        FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this network interface.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById 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
    ) -> 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object from 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 FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityNetworkInterfaceIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN(
        FlowLogCollectorTargetPrototypeSubnetIdentity):
    """
    FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN.

    :attr str crn: The CRN for this subnet.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN 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
    ) -> 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object from 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 FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref(
        FlowLogCollectorTargetPrototypeSubnetIdentity):
    """
    FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref.

    :attr str href: The URL for this subnet.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref 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
    ) -> 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object from 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 FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById(
        FlowLogCollectorTargetPrototypeSubnetIdentity):
    """
    FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById.

    :attr str id: The unique identifier for this subnet.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById 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
    ) -> 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object from 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 FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN(
        FlowLogCollectorTargetPrototypeVPCIdentity):
    """
    FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN.

    :attr str crn: The CRN for this VPC.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN 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
    ) -> 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object from 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 FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref(
        FlowLogCollectorTargetPrototypeVPCIdentity):
    """
    FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref.

    :attr str href: The URL for this VPC.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref 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
    ) -> 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object from 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 FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self,
        other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self,
        other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById(
        FlowLogCollectorTargetPrototypeVPCIdentity):
    """
    FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById.

    :attr str id: The unique identifier for this VPC.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById 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
    ) -> 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object from 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 FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec(
        InstanceGroupManagerActionPrototypeScheduledActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    """

    def __init__(self, *, name: str = None, cron_spec: str = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec object.

        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup',
                'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager'
            ]))
        raise Exception(msg)


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt(
        InstanceGroupManagerActionPrototypeScheduledActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    """

    def __init__(self, *, name: str = None, run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt object.

        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup',
                'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager'
            ]))
        raise Exception(msg)


class InstanceGroupManagerActionScheduledActionGroup(
        InstanceGroupManagerActionScheduledAction):
    """
    InstanceGroupManagerActionScheduledActionGroup.

    :attr bool auto_delete: If set to `true`, this scheduled action will be
          automatically deleted after it has finished and the `auto_delete_timeout` time
          has passed.
    :attr int auto_delete_timeout: Amount of time in hours that are required to pass
          before the scheduled action will be automatically deleted once it has finished.
          If this value is 0, the action will be deleted on completion.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The user-defined name for this instance group manager action.
          Names must be unique within the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was modified.
    :attr str action_type: The type of action for the instance group.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr datetime last_applied_at: (optional) The date and time the scheduled
          action was last applied. If empty the action has never been applied.
    :attr datetime next_run_at: (optional) The date and time the scheduled action
          will next run. If empty the system is currently calculating the next run time.
    :attr InstanceGroupManagerScheduledActionGroupGroup group:
    """

    def __init__(self,
                 auto_delete: bool,
                 auto_delete_timeout: int,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 status: str,
                 updated_at: datetime,
                 action_type: str,
                 group: 'InstanceGroupManagerScheduledActionGroupGroup',
                 *,
                 cron_spec: str = None,
                 last_applied_at: datetime = None,
                 next_run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionScheduledActionGroup object.

        :param bool auto_delete: If set to `true`, this scheduled action will be
               automatically deleted after it has finished and the `auto_delete_timeout`
               time has passed.
        :param int auto_delete_timeout: Amount of time in hours that are required
               to pass before the scheduled action will be automatically deleted once it
               has finished. If this value is 0, the action will be deleted on completion.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The user-defined name for this instance group manager
               action. Names must be unique within the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was modified.
        :param str action_type: The type of action for the instance group.
        :param InstanceGroupManagerScheduledActionGroupGroup group:
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param datetime last_applied_at: (optional) The date and time the scheduled
               action was last applied. If empty the action has never been applied.
        :param datetime next_run_at: (optional) The date and time the scheduled
               action will next run. If empty the system is currently calculating the next
               run time.
        """
        # pylint: disable=super-init-not-called
        self.auto_delete = auto_delete
        self.auto_delete_timeout = auto_delete_timeout
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type
        self.status = status
        self.updated_at = updated_at
        self.action_type = action_type
        self.cron_spec = cron_spec
        self.last_applied_at = last_applied_at
        self.next_run_at = next_run_at
        self.group = group

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceGroupManagerActionScheduledActionGroup':
        """Initialize a InstanceGroupManagerActionScheduledActionGroup object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError(
                'Required property \'auto_delete\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'auto_delete_timeout' in _dict:
            args['auto_delete_timeout'] = _dict.get('auto_delete_timeout')
        else:
            raise ValueError(
                'Required property \'auto_delete_timeout\' not present in InstanceGroupManagerActionScheduledActionGroup 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 InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'action_type' in _dict:
            args['action_type'] = _dict.get('action_type')
        else:
            raise ValueError(
                'Required property \'action_type\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'last_applied_at' in _dict:
            args['last_applied_at'] = string_to_datetime(
                _dict.get('last_applied_at'))
        if 'next_run_at' in _dict:
            args['next_run_at'] = string_to_datetime(_dict.get('next_run_at'))
        if 'group' in _dict:
            args[
                'group'] = InstanceGroupManagerScheduledActionGroupGroup.from_dict(
                    _dict.get('group'))
        else:
            raise ValueError(
                'Required property \'group\' not present in InstanceGroupManagerActionScheduledActionGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionScheduledActionGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(
                self,
                'auto_delete_timeout') and self.auto_delete_timeout is not None:
            _dict['auto_delete_timeout'] = self.auto_delete_timeout
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'action_type') and self.action_type is not None:
            _dict['action_type'] = self.action_type
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self,
                   'last_applied_at') and self.last_applied_at is not None:
            _dict['last_applied_at'] = datetime_to_string(self.last_applied_at)
        if hasattr(self, 'next_run_at') and self.next_run_at is not None:
            _dict['next_run_at'] = datetime_to_string(self.next_run_at)
        if hasattr(self, 'group') and self.group is not None:
            _dict['group'] = self.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 InstanceGroupManagerActionScheduledActionGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self,
               other: 'InstanceGroupManagerActionScheduledActionGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self,
               other: 'InstanceGroupManagerActionScheduledActionGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'

    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """
        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'

    class ActionTypeEnum(str, Enum):
        """
        The type of action for the instance group.
        """
        SCHEDULED = 'scheduled'


class InstanceGroupManagerActionScheduledActionManager(
        InstanceGroupManagerActionScheduledAction):
    """
    InstanceGroupManagerActionScheduledActionManager.

    :attr bool auto_delete: If set to `true`, this scheduled action will be
          automatically deleted after it has finished and the `auto_delete_timeout` time
          has passed.
    :attr int auto_delete_timeout: Amount of time in hours that are required to pass
          before the scheduled action will be automatically deleted once it has finished.
          If this value is 0, the action will be deleted on completion.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The user-defined name for this instance group manager action.
          Names must be unique within the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was modified.
    :attr str action_type: The type of action for the instance group.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr datetime last_applied_at: (optional) The date and time the scheduled
          action was last applied. If empty the action has never been applied.
    :attr datetime next_run_at: (optional) The date and time the scheduled action
          will next run. If empty the system is currently calculating the next run time.
    :attr InstanceGroupManagerScheduledActionManagerManager manager:
    """

    def __init__(self,
                 auto_delete: bool,
                 auto_delete_timeout: int,
                 created_at: datetime,
                 href: str,
                 id: str,
                 name: str,
                 resource_type: str,
                 status: str,
                 updated_at: datetime,
                 action_type: str,
                 manager: 'InstanceGroupManagerScheduledActionManagerManager',
                 *,
                 cron_spec: str = None,
                 last_applied_at: datetime = None,
                 next_run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionScheduledActionManager object.

        :param bool auto_delete: If set to `true`, this scheduled action will be
               automatically deleted after it has finished and the `auto_delete_timeout`
               time has passed.
        :param int auto_delete_timeout: Amount of time in hours that are required
               to pass before the scheduled action will be automatically deleted once it
               has finished. If this value is 0, the action will be deleted on completion.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The user-defined name for this instance group manager
               action. Names must be unique within the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was modified.
        :param str action_type: The type of action for the instance group.
        :param InstanceGroupManagerScheduledActionManagerManager manager:
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param datetime last_applied_at: (optional) The date and time the scheduled
               action was last applied. If empty the action has never been applied.
        :param datetime next_run_at: (optional) The date and time the scheduled
               action will next run. If empty the system is currently calculating the next
               run time.
        """
        # pylint: disable=super-init-not-called
        self.auto_delete = auto_delete
        self.auto_delete_timeout = auto_delete_timeout
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type
        self.status = status
        self.updated_at = updated_at
        self.action_type = action_type
        self.cron_spec = cron_spec
        self.last_applied_at = last_applied_at
        self.next_run_at = next_run_at
        self.manager = manager

    @classmethod
    def from_dict(
            cls,
            _dict: Dict) -> 'InstanceGroupManagerActionScheduledActionManager':
        """Initialize a InstanceGroupManagerActionScheduledActionManager object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError(
                'Required property \'auto_delete\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'auto_delete_timeout' in _dict:
            args['auto_delete_timeout'] = _dict.get('auto_delete_timeout')
        else:
            raise ValueError(
                'Required property \'auto_delete_timeout\' not present in InstanceGroupManagerActionScheduledActionManager 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 InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError(
                'Required property \'resource_type\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError(
                'Required property \'status\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError(
                'Required property \'updated_at\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'action_type' in _dict:
            args['action_type'] = _dict.get('action_type')
        else:
            raise ValueError(
                'Required property \'action_type\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'last_applied_at' in _dict:
            args['last_applied_at'] = string_to_datetime(
                _dict.get('last_applied_at'))
        if 'next_run_at' in _dict:
            args['next_run_at'] = string_to_datetime(_dict.get('next_run_at'))
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        else:
            raise ValueError(
                'Required property \'manager\' not present in InstanceGroupManagerActionScheduledActionManager JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionScheduledActionManager object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(
                self,
                'auto_delete_timeout') and self.auto_delete_timeout is not None:
            _dict['auto_delete_timeout'] = self.auto_delete_timeout
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'action_type') and self.action_type is not None:
            _dict['action_type'] = self.action_type
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self,
                   'last_applied_at') and self.last_applied_at is not None:
            _dict['last_applied_at'] = datetime_to_string(self.last_applied_at)
        if hasattr(self, 'next_run_at') and self.next_run_at is not None:
            _dict['next_run_at'] = datetime_to_string(self.next_run_at)
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.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 InstanceGroupManagerActionScheduledActionManager object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
            self,
            other: 'InstanceGroupManagerActionScheduledActionManager') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
            self,
            other: 'InstanceGroupManagerActionScheduledActionManager') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """
        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'

    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """
        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'

    class ActionTypeEnum(str, Enum):
        """
        The type of action for the instance group.
        """
        SCHEDULED = 'scheduled'


class InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref(
        InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototype):
    """
    InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref.

    :attr int max_membership_count: (optional) The maximum number of members the
          instance group should have at the scheduled time.
    :attr int min_membership_count: (optional) The minimum number of members the
          instance group should have at the scheduled time.
    :attr str href: The URL for this instance group manager.
    """

    def __init__(self,
                 href: str,
                 *,
                 max_membership_count: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref object.

        :param str href: The URL for this instance group manager.
        :param int max_membership_count: (optional) The maximum number of members
               the instance group should have at the scheduled time.
        :param int min_membership_count: (optional) The minimum number of members
               the instance group should have at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref':
        """Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref object from a json dictionary."""
        args = {}
        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 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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, '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 InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById(
        InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototype):
    """
    InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById.

    :attr int max_membership_count: (optional) The maximum number of members the
          instance group should have at the scheduled time.
    :attr int min_membership_count: (optional) The minimum number of members the
          instance group should have at the scheduled time.
    :attr str id: The unique identifier for this instance group manager.
    """

    def __init__(self,
                 id: str,
                 *,
                 max_membership_count: int = None,
                 min_membership_count: int = None) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById object.

        :param str id: The unique identifier for this instance group manager.
        :param int max_membership_count: (optional) The maximum number of members
               the instance group should have at the scheduled time.
        :param int min_membership_count: (optional) The minimum number of members
               the instance group should have at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById':
        """Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById object from a json dictionary."""
        args = {}
        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 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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, '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 InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerScheduledActionByManagerManagerAutoScalePrototypeInstanceGroupManagerScheduledActionManagerAutoScalePrototypeInstanceGroupManagerIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN(
        InstancePlacementTargetPrototypeDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN.

    :attr str crn: The CRN for this dedicated host group.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object.

        :param str crn: The CRN for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object from 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 InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref(
        InstancePlacementTargetPrototypeDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref.

    :attr str href: The URL for this dedicated host group.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object.

        :param str href: The URL for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object from 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 InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById(
        InstancePlacementTargetPrototypeDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById.

    :attr str id: The unique identifier for this dedicated host group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object.

        :param str id: The unique identifier for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object from 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 InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN(
        InstancePlacementTargetPrototypeDedicatedHostIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN.

    :attr str crn: The CRN for this dedicated host.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object.

        :param str crn: The CRN for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object from 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 InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref(
        InstancePlacementTargetPrototypeDedicatedHostIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref.

    :attr str href: The URL for this dedicated host.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object.

        :param str href: The URL for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object from 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 InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById(
        InstancePlacementTargetPrototypeDedicatedHostIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById.

    :attr str id: The unique identifier for this dedicated host.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object.

        :param str id: The unique identifier for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object from 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 InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(
        LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref 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
    ) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(
        LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById 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
    ) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(
        LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref 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
    ) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(
        LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById 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
    ) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById'
    ) -> 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 PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress(
        PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress.

    :attr str address: The globally unique IP address.
    """

    def __init__(self, address: str) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress 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
    ) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError(
                'Required property \'address\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object from 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 PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN(
        PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN.

    :attr str crn: The CRN for this floating IP.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN 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
    ) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object from 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 PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref(
        PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref.

    :attr str href: The URL for this floating IP.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref 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
    ) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object from 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 PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById(
        PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById.

    :attr str id: The unique identifier for this floating IP.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById 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
    ) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object from 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 PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN(
        ReservedIPTargetPrototypeEndpointGatewayIdentity):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN.

    :attr str crn: The CRN for this endpoint gateway.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object.

        :param str crn: The CRN for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN':
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object from 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 ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref(
        ReservedIPTargetPrototypeEndpointGatewayIdentity):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref.

    :attr str href: The URL for this endpoint gateway.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object.

        :param str href: The URL for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref':
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object from 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 ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById(
        ReservedIPTargetPrototypeEndpointGatewayIdentity):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById.

    :attr str id: The unique identifier for this endpoint gateway.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object.

        :param str id: The unique identifier for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById':
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object from 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 ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref(
        RouteNextHopPrototypeVPNGatewayConnectionIdentity):
    """
    RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref.

    :attr str href: The VPN connection's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object.

        :param str href: The VPN connection's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref':
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from 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 RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById(
        RouteNextHopPrototypeVPNGatewayConnectionIdentity):
    """
    RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById.

    :attr str id: The unique identifier for this VPN gateway connection.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object.

        :param str id: The unique identifier for this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById':
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from 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 RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN(
        SecurityGroupRuleRemotePatchSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN.

    :attr str crn: The security group's CRN.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN 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
    ) -> 'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN':
        """Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN object from 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 SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref(
        SecurityGroupRuleRemotePatchSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref.

    :attr str href: The security group's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref 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
    ) -> 'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref':
        """Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref object from 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 SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById(
        SecurityGroupRuleRemotePatchSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById.

    :attr str id: The unique identifier for this security group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById 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
    ) -> 'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById':
        """Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById object from 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 SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN(
        SecurityGroupRuleRemotePrototypeSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN.

    :attr str crn: The security group's CRN.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN 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
    ) -> 'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN':
        """Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN object from 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 SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref(
        SecurityGroupRuleRemotePrototypeSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref.

    :attr str href: The security group's canonical URL.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref 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
    ) -> 'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref':
        """Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref object from 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 SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById(
        SecurityGroupRuleRemotePrototypeSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById.

    :attr str id: The unique identifier for this security group.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById 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
    ) -> 'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById':
        """Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById object from 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 SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN(
        VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN.

    :attr str crn: The CRN for this volume.
    """

    def __init__(self, crn: str) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN 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
    ) -> 'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN':
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN object from 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 VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByCRN'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref(
        VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref.

    :attr str href: The URL for this volume.
    """

    def __init__(self, href: str) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref 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
    ) -> 'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref':
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref object from 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 VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityByHref'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById(
        VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById.

    :attr str id: The unique identifier for this volume.
    """

    def __init__(self, id: str) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById 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
    ) -> 'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById':
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError(
                'Required property \'id\' not present in VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById object from 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 VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentityVolumeIdentityById'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity(
        VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext
):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity.

    :attr int iops: (optional) The bandwidth for the volume.
    :attr str name: (optional) The unique user-defined name for this volume.
    :attr VolumeProfileIdentity profile: The profile to use for this volume.
    :attr int capacity: The capacity of the volume in gigabytes. The specified
          minimum and maximum capacity values for creating or updating volumes may expand
          in the future.
    :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`.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 capacity: int,
                 *,
                 iops: int = None,
                 name: str = None,
                 encryption_key: 'EncryptionKeyIdentity' = None) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param int capacity: The capacity of the volume in gigabytes. 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.
        :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`.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.name = name
        self.profile = profile
        self.capacity = capacity
        self.encryption_key = encryption_key

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity':
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        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 VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON'
            )
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError(
                'Required property \'capacity\' not present in VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON'
            )
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from 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, '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, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        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 VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup(
        InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr InstanceGroupManagerScheduledActionGroupPrototype group:
    """

    def __init__(self,
                 group: 'InstanceGroupManagerScheduledActionGroupPrototype',
                 *,
                 name: str = None,
                 cron_spec: str = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object.

        :param InstanceGroupManagerScheduledActionGroupPrototype group:
        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.cron_spec = cron_spec
        self.group = group

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'group' in _dict:
            args[
                'group'] = InstanceGroupManagerScheduledActionGroupPrototype.from_dict(
                    _dict.get('group'))
        else:
            raise ValueError(
                'Required property \'group\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object from 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, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'group') and self.group is not None:
            _dict['group'] = self.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 InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager(
        InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr InstanceGroupManagerScheduledActionByManagerManager manager:
    """

    def __init__(self,
                 manager: 'InstanceGroupManagerScheduledActionByManagerManager',
                 *,
                 name: str = None,
                 cron_spec: str = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object.

        :param InstanceGroupManagerScheduledActionByManagerManager manager:
        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.cron_spec = cron_spec
        self.manager = manager

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        else:
            raise ValueError(
                'Required property \'manager\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object from 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, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.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 InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup(
        InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    :attr InstanceGroupManagerScheduledActionGroupPrototype group:
    """

    def __init__(self,
                 group: 'InstanceGroupManagerScheduledActionGroupPrototype',
                 *,
                 name: str = None,
                 run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object.

        :param InstanceGroupManagerScheduledActionGroupPrototype group:
        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.run_at = run_at
        self.group = group

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'run_at' in _dict:
            args['run_at'] = string_to_datetime(_dict.get('run_at'))
        if 'group' in _dict:
            args[
                'group'] = InstanceGroupManagerScheduledActionGroupPrototype.from_dict(
                    _dict.get('group'))
        else:
            raise ValueError(
                'Required property \'group\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object from 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, 'run_at') and self.run_at is not None:
            _dict['run_at'] = datetime_to_string(self.run_at)
        if hasattr(self, 'group') and self.group is not None:
            _dict['group'] = self.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 InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager(
        InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager.

    :attr str name: (optional) The user-defined name for this instance group manager
          action. Names must be unique within the instance group manager.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    :attr InstanceGroupManagerScheduledActionByManagerManager manager:
    """

    def __init__(self,
                 manager: 'InstanceGroupManagerScheduledActionByManagerManager',
                 *,
                 name: str = None,
                 run_at: datetime = None) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object.

        :param InstanceGroupManagerScheduledActionByManagerManager manager:
        :param str name: (optional) The user-defined name for this instance group
               manager action. Names must be unique within the instance group manager.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.run_at = run_at
        self.manager = manager

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'run_at' in _dict:
            args['run_at'] = string_to_datetime(_dict.get('run_at'))
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        else:
            raise ValueError(
                'Required property \'manager\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object from 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, 'run_at') and self.run_at is not None:
            _dict['run_at'] = datetime_to_string(self.run_at)
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.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 InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager'
    ) -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(
        self, other:
        'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager'
    ) -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other
