# coding: utf-8

# (C) Copyright IBM Corp. 2020, 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.12.3-81ed37e0-20200929-215851
"""
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 VpcClassicV1(BaseService):
    """The vpc_classic V1 service."""

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

    @classmethod
    def new_instance(
        cls,
        version: str = '2021-01-12',
        service_name: str = DEFAULT_SERVICE_NAME,
        generation: int = 1,
    ) -> 'VpcClassicV1':
        """
        Return a new client for the vpc_classic 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-01-12',
        authenticator: Authenticator = None,
        generation: int = 1,
    ) -> None:
        """
        Construct a new client for the vpc_classic 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,
                  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 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,
            '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 associated with the VPC are automatically deleted. If the default
        network ACL was automatically created, it is 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_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 is to belong to.
        :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,
                        **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 dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteCollection` object
        """

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

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

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

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

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

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

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

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

        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

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

    def list_subnets(self,
                     *,
                     start: str = None,
                     limit: int = 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 dict headers: 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
        }

        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 or public gateways.

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

    #########################
    # 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. System-provided
        images are not allowed to be deleted. An image with a `status` of `pending`,
        `tentative`, or `deleting` cannot be deleted.

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

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

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

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

        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. System-provided images are not allowed to be
        updated. An image with a `status` of `deleting` cannot be updated.

        :param str id: The image identifier.
        :param 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,
                  *,
                  start: str = None,
                  limit: int = 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 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 `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,
            'start': start,
            'limit': limit
        }

        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 user-defined name for this key.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param 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,
                               *,
                               start: str = None,
                               limit: int = None,
                               **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 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 `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,
            'start': start,
            'limit': limit
        }

        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_instances(self,
                       *,
                       start: str = None,
                       limit: int = None,
                       network_interfaces_subnet_id: str = None,
                       network_interfaces_subnet_crn: str = None,
                       network_interfaces_subnet_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 network_interfaces_subnet_id: (optional) Filters the collection
               to instances on the subnet of the specified identifier.
        :param str network_interfaces_subnet_crn: (optional) Filters the collection
               to instances on the subnet of the specified CRN.
        :param str network_interfaces_subnet_name: (optional) Filters the
               collection to instances on the subnet of 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 `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,
            'network_interfaces.subnet.id': network_interfaces_subnet_id,
            'network_interfaces.subnet.crn': network_interfaces_subnet_crn,
            'network_interfaces.subnet.name': network_interfaces_subnet_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,
                               **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 dict headers: 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}
        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 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 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 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 in a provided volume
        attachment patch. The volume attachment patch object is structured in the same way
        as a retrieved volume attachment and can contain an updated name.

        :param str instance_id: The instance identifier.
        :param str id: The volume attachment identifier.
        :param 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

    #########################
    # 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,
                             **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 dict headers: 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
        }

        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,
            **kwargs) -> DetailedResponse:
        """
        Create a public gateway.

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

        :param VPCIdentity vpc: The VPC this public gateway will serve.
        :param ZoneIdentity zone: The zone where this public gateway will be
               created.
        :param 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 dict headers: 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)
        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
        }
        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,
                          **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 dict headers: 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
        }

        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,
                          **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 dict headers: 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
        }

        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 is structured in the same way as a retrieved rule and contains
        only the information to be updated.

        :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,
                             *,
                             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 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,
            '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. Security group names must be unique, within the scope of an account.
        :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,
                                               **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 dict headers: 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}

        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 provided in a rule
        patch object. The patch object is structured in the same way as a retrieved
        security group rule and needs to contain only the information to be updated.

        :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

    #########################
    # 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_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,
            resource_group: 'ResourceGroupIdentity' = 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 ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancer` object
        """

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

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

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

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

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

        response = self.send(request)
        return response

    def delete_load_balancer(self, id: str, **kwargs) -> DetailedResponse:
        """
        Delete a load balancer.

        This request deletes a load balancer. This operation cannot be reversed.

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

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

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

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

        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. Each listener in the load
               balancer must have a unique
               `port` and `protocol` combination.
        :param str protocol: The listener protocol.
        :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.
        :param str value: Value to be matched for rule condition.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyRule` object
        """

        if load_balancer_id is None:
            raise ValueError('load_balancer_id must be provided')
        if listener_id is None:
            raise ValueError('listener_id must be provided')
        if policy_id is None:
            raise ValueError('policy_id must be provided')
        if condition is None:
            raise ValueError('condition must be provided')
        if type is None:
            raise ValueError('type must be provided')
        if value is None:
            raise ValueError('value must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_load_balancer_listener_policy_rule')
        headers.update(sdk_headers)

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

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

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

        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.
        :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:
        """
        Update load balancer pool members.

        This request updates members of the load balancer pool from a collection of member
        prototype objects.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param List[LoadBalancerPoolMemberPrototype] members: Array of pool member
               prototype objects.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerPoolMemberCollection` object
        """

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

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

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

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

        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


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'


##############################################################################
# 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.
    """

    def __init__(self,
                 address_prefixes: List['AddressPrefix'],
                 first: 'AddressPrefixCollectionFirst',
                 limit: 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 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

    @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'))
        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()
        return _dict

    def _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 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 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, 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 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.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 '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, '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 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 str status: The status of the floating IP.
    :attr FloatingIPTarget target: (optional) The target of this floating IP.
    :attr ZoneReference zone: The zone the floating IP resides in.
    """

    def __init__(self,
                 address: str,
                 created_at: datetime,
                 crn: str,
                 href: str,
                 id: str,
                 name: str,
                 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 str status: The status of the floating IP.
        :param ZoneReference zone: The zone the floating IP resides in.
        :param FloatingIPTarget target: (optional) The target of this floating IP.
        """
        self.address = address
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        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 '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, '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.
    """

    def __init__(self,
                 first: 'FloatingIPCollectionFirst',
                 floating_ips: List['FloatingIP'],
                 limit: 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 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

    @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'))
        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()
        return _dict

    def _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.
    """

    def __init__(self, *, name: str = 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.
        """
        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 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) -> 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.
        """
        self.address = address
        self.crn = crn
        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 '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, '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 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 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'

    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'

    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        """
        TRIPLE_DES = 'triple_des'
        AES128 = 'aes128'
        AES256 = 'aes256'


class IKEPolicyReference():
    """
    IKEPolicyReference.

    :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) -> 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.
        """
        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 '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, '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 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'

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

    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        """
        TRIPLE_DES = 'triple_des'
        AES128 = 'aes128'
        AES256 = 'aes256'

    class PfsEnum(str, Enum):
        """
        Perfect Forward Secrecy.
        """
        DISABLED = 'disabled'
        GROUP_14 = 'group_14'
        GROUP_2 = 'group_2'
        GROUP_5 = 'group_5'


class IPsecPolicyReference():
    """
    IPsecPolicyReference.

    :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) -> 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.
        """
        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 '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, '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 Image():
    """
    Image.

    :attr datetime created_at: The date and time that the image was created.
    :attr str crn: The CRN for this image.
    :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.
    :attr str visibility: Whether the image is publicly visible or private to the
          account.
    """

    def __init__(self,
                 created_at: datetime,
                 crn: str,
                 file: 'ImageFile',
                 href: str,
                 id: str,
                 name: str,
                 resource_group: 'ResourceGroupReference',
                 status: str,
                 visibility: str,
                 *,
                 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 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.
        :param str visibility: Whether the image is publicly visible or private to
               the account.
        :param int minimum_provisioned_size: (optional) The minimum size (in
               gigabytes) of a volume onto which this image may be provisioned.
               This property may be absent if the image has a `status` of `pending`,
               `tentative`, or
               `failed`.
        :param OperatingSystem operating_system: (optional) The operating system
               included in this image.
        """
        self.created_at = created_at
        self.crn = crn
        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.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 '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 '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, '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, 'visibility') and self.visibility is not None:
            _dict['visibility'] = self.visibility
        return _dict

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

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

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

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

    class StatusEnum(str, Enum):
        """
        The status of this image.
        """
        AVAILABLE = 'available'
        DELETING = 'deleting'
        DEPRECATED = 'deprecated'
        FAILED = 'failed'
        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 int size: (optional) The size of the stored image file rounded up to the
          next gigabyte.
          This property may be absent if the associated image has a `status` of `pending`
          or
          `failed`.
    """

    def __init__(self, *, size: int = None) -> None:
        """
        Initialize a ImageFile object.

        :param int size: (optional) The size of the stored image file rounded up to
               the next gigabyte.
               This property may be absent if the associated image has a `status` of
               `pending` or
               `failed`.
        """
        self.size = size

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

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

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

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

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

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

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


class ImageFilePrototype():
    """
    ImageFilePrototype.

    :attr str href: The Cloud Object Store (COS) location of the image file.
    """

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

        :param str href: The Cloud Object Store (COS) location of the image file.
        """
        self.href = href

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

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

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

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

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

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

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


class ImageIdentity():
    """
    Identifies an image by a unique property.

    """

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

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


class 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 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) -> 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.
        """
        self.crn = crn
        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 '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, '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 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 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 in gigabytes.
    :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 InstanceVCPU vcpu: The virtual server instance VCPU configuration.
    :attr List[VolumeAttachmentReferenceInstanceContext] volume_attachments:
          Collection of the virtual server instance's volume attachments, including the
          boot volume attachment.
    :attr VPCReference vpc: The VPC the virtual server instance resides in.
    :attr ZoneReference zone: The zone the virtual server instance resides in.
    """

    def __init__(
            self,
            bandwidth: int,
            boot_volume_attachment: 'VolumeAttachmentReferenceInstanceContext',
            created_at: datetime,
            crn: str,
            href: str,
            id: str,
            memory: int,
            name: str,
            network_interfaces: List[
                'NetworkInterfaceInstanceContextReference'],
            primary_network_interface:
        'NetworkInterfaceInstanceContextReference',
            profile: 'InstanceProfileReference',
            resource_group: 'ResourceGroupReference',
            status: str,
            vcpu: 'InstanceVCPU',
            volume_attachments: List[
                'VolumeAttachmentReferenceInstanceContext'],
            vpc: 'VPCReference',
            zone: 'ZoneReference',
            *,
            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 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 in gigabytes.
        :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 InstanceVCPU vcpu: The virtual server instance VCPU configuration.
        :param List[VolumeAttachmentReferenceInstanceContext] volume_attachments:
               Collection of the virtual server instance's volume attachments, including
               the boot volume attachment.
        :param VPCReference vpc: The VPC the virtual server instance resides in.
        :param ZoneReference zone: The zone the virtual server instance resides in.
        :param 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.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.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 '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 '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, '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, '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 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,
                 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 datetime started_at: (optional) The date and time that the action
               was started.
        """
        self.completed_at = completed_at
        self.created_at = created_at
        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 '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, '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'
        RESET = 'reset'


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 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).
    """

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

        :param str name: (optional) The user-defined name for this virtual server
               instance (and default system hostname).
        """
        self.name = name

    @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')
        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
        return _dict

    def _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 InstanceProfile():
    """
    InstanceProfile.

    :attr InstanceProfileBandwidth bandwidth:
    :attr str crn: The CRN for this virtual server instance profile.
    :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 str name: The globally unique name for this virtual server instance
          profile.
    :attr InstanceProfilePortSpeed port_speed:
    """

    def __init__(self,
                 bandwidth: 'InstanceProfileBandwidth',
                 crn: str,
                 href: str,
                 name: str,
                 port_speed: 'InstanceProfilePortSpeed',
                 *,
                 family: str = None) -> None:
        """
        Initialize a InstanceProfile object.

        :param InstanceProfileBandwidth bandwidth:
        :param str crn: The CRN for this virtual server instance profile.
        :param str href: The URL for this virtual server instance profile.
        :param str name: The globally unique name for this virtual server instance
               profile.
        :param InstanceProfilePortSpeed port_speed:
        :param str family: (optional) The product family this virtual server
               instance profile belongs to.
        """
        self.bandwidth = bandwidth
        self.crn = crn
        self.family = family
        self.href = href
        self.name = name
        self.port_speed = port_speed

    @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 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' 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 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError(
                'Required property \'name\' 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'
            )
        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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        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, '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()
        return _dict

    def _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 InstanceProfileCollectionFirst 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 InstanceProfileCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[InstanceProfile] profiles: Collection of virtual server instance
          profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(self,
                 first: 'InstanceProfileCollectionFirst',
                 limit: int,
                 profiles: List['InstanceProfile'],
                 total_count: int,
                 *,
                 next: 'InstanceProfileCollectionNext' = None) -> None:
        """
        Initialize a InstanceProfileCollection object.

        :param InstanceProfileCollectionFirst 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[InstanceProfile] profiles: Collection of virtual server
               instance profiles.
        :param int total_count: The total number of resources across all pages.
        :param InstanceProfileCollectionNext 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) -> 'InstanceProfileCollection':
        """Initialize a InstanceProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceProfileCollectionFirst.from_dict(
                _dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in InstanceProfileCollection JSON'
            )
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in InstanceProfileCollection JSON'
            )
        if 'next' in _dict:
            args['next'] = InstanceProfileCollectionNext.from_dict(
                _dict.get('next'))
        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'
            )
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError(
                'Required property \'total_count\' 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, '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 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 InstanceProfileCollectionFirst():
    """
    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 InstanceProfileCollectionFirst object.

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

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

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

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

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


class InstanceProfileCollectionNext():
    """
    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 InstanceProfileCollectionNext object.

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

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

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

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

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


class InstanceProfileIdentity():
    """
    Identifies an instance profile by a unique property.

    """

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

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


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 crn: The CRN for this virtual server instance profile.
    :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, crn: str, href: str, name: str) -> None:
        """
        Initialize a InstanceProfileReference object.

        :param str crn: The CRN for this virtual server instance profile.
        :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.crn = crn
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileReference':
        """Initialize a InstanceProfileReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError(
                'Required property \'crn\' not present in InstanceProfileReference JSON'
            )
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError(
                'Required property \'href\' not present in InstanceProfileReference JSON'
            )
        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, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

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

    def __str__(self) -> str:
        """Return a `str` version of this 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 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 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 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,
                 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 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 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']))
        raise Exception(msg)


class InstanceReference():
    """
    InstanceReference.

    :attr str crn: The CRN for this virtual server instance.
    :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) -> 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).
        """
        self.crn = crn
        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 '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, '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 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 user-defined name for this key.
    :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 user-defined name for this key.
        :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 KeyCollectionFirst first: A link to the first page of resources.
    :attr List[Key] keys: Collection of keys.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr KeyCollectionNext 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: 'KeyCollectionFirst',
                 keys: List['Key'],
                 limit: int,
                 total_count: int,
                 *,
                 next: 'KeyCollectionNext' = None) -> None:
        """
        Initialize a KeyCollection object.

        :param KeyCollectionFirst first: A link to the first page of resources.
        :param List[Key] keys: Collection of keys.
        :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 KeyCollectionNext 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.keys = keys
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyCollection':
        """Initialize a KeyCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = KeyCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError(
                'Required property \'first\' not present in KeyCollection JSON')
        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')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError(
                'Required property \'limit\' not present in KeyCollection JSON')
        if 'next' in _dict:
            args['next'] = KeyCollectionNext.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 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, 'first') and self.first is not None:
            _dict['first'] = self.first.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            _dict['keys'] = [x.to_dict() for x in self.keys]
        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 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 KeyCollectionFirst():
    """
    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 KeyCollectionFirst object.

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

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

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

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

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


class KeyCollectionNext():
    """
    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 KeyCollectionNext object.

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

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

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

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

    def __ne__(self, other: 'KeyCollectionNext') -> 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 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 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[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'], provisioning_status: str,
                 public_ips: List['IP'],
                 resource_group: 'ResourceGroupReference',
                 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 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[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.provisioning_status = provisioning_status
        self.public_ips = public_ips
        self.resource_group = resource_group
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancer':
        """Initialize a LoadBalancer object from a json dictionary."""
        args = {}
        if '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 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError(
                'Required property \'provisioning_status\' not present in LoadBalancer JSON'
            )
        if 'public_ips' in _dict:
            args['public_ips'] = [
                IP.from_dict(x) for x in _dict.get('public_ips')
            ]
        else:
            raise ValueError(
                'Required property \'public_ips\' not present in LoadBalancer JSON'
            )
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(
                _dict.get('resource_group'))
        else:
            raise ValueError(
                'Required property \'resource_group\' not present in LoadBalancer JSON'
            )
        if 'subnets' in _dict:
            args['subnets'] = [
                SubnetReference.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in LoadBalancer JSON'
            )
        return cls(**args)

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

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

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

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

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

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

    class OperatingStatusEnum(str, Enum):
        """
        The operating status of this load balancer.
        """
        OFFLINE = 'offline'
        ONLINE = 'online'

    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this load balancer.
        """
        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        UPDATE_PENDING = 'update_pending'


class LoadBalancerCollection():
    """
    LoadBalancerCollection.

    :attr List[LoadBalancer] load_balancers: Collection of load balancers.
    """

    def __init__(self, load_balancers: List['LoadBalancer']) -> None:
        """
        Initialize a LoadBalancerCollection object.

        :param List[LoadBalancer] load_balancers: Collection of load balancers.
        """
        self.load_balancers = load_balancers

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

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

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

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

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

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

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


class 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. Each listener in the load balancer
          must have a unique
          `port` and `protocol` combination.
    :attr str protocol: The listener protocol.
    :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. Each listener in the load
               balancer must have a unique
               `port` and `protocol` combination.
        :param str protocol: The listener protocol.
        :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.
        """
        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. Each listener in the load
          balancer must have a unique
          `port` and `protocol` combination.
    :attr str protocol: (optional) The listener protocol.
    """

    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. Each listener in the
               load balancer must have a unique
               `port` and `protocol` combination.
        :param str protocol: (optional) The listener protocol.
        """
        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.
        """
        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 str href: The listener policy's canonical URL.
    :attr str id: The policy's unique identifier.
    """

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

        :param str href: The listener policy's canonical URL.
        :param str id: The policy's unique identifier.
        """
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyReference':
        """Initialize a LoadBalancerListenerPolicyReference object from a json dictionary."""
        args = {}
        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, '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 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) HTTP header field. This is only applicable to
          "header" rule type.
    :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.
    :attr str value: Value to be matched for rule condition.
    """

    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.
        :param str value: Value to be matched for rule condition.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        """
        self.condition = condition
        self.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.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'


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) HTTP header field. This is only applicable to
          "header" rule type.
    :attr str type: (optional) The type of the rule.
    :attr str value: (optional) Value to be matched for rule condition.
    """

    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) HTTP header field. This is only applicable to
               "header" rule type.
        :param str type: (optional) The type of the rule.
        :param str value: (optional) Value to be matched for rule condition.
        """
        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.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'


class LoadBalancerListenerPolicyRulePrototype():
    """
    LoadBalancerListenerPolicyRulePrototype.

    :attr str condition: The condition of the rule.
    :attr str field: (optional) HTTP header field. This is only applicable to
          "header" rule type.
    :attr str type: The type of the rule.
    :attr str value: Value to be matched for rule condition.
    """

    def __init__(self,
                 condition: str,
                 type: str,
                 value: str,
                 *,
                 field: str = None) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePrototype object.

        :param str condition: The condition of the rule.
        :param str type: The type of the rule.
        :param str value: Value to be matched for rule condition.
        :param str field: (optional) HTTP header field. This is only applicable to
               "header" rule type.
        """
        self.condition = condition
        self.field = field
        self.type = type
        self.value = value

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

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

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

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

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

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

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

    class ConditionEnum(str, Enum):
        """
        The condition of the rule.
        """
        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'

    class TypeEnum(str, Enum):
        """
        The type of the rule.
        """
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'


class LoadBalancerListenerPolicyRuleReference():
    """
    LoadBalancerListenerPolicyRuleReference.

    :attr str href: The rule's canonical URL.
    :attr str id: The rule's unique identifier.
    """

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

        :param str href: The rule's canonical URL.
        :param str id: The rule's unique identifier.
        """
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls,
                  _dict: Dict) -> 'LoadBalancerListenerPolicyRuleReference':
        """Initialize a LoadBalancerListenerPolicyRuleReference object from a json dictionary."""
        args = {}
        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, '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 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. Each listener in the load balancer
          must have a unique
          `port` and `protocol` combination.
    :attr str protocol: The listener protocol.
    """

    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. Each listener in the load
               balancer must have a unique
               `port` and `protocol` combination.
        :param str protocol: The listener protocol.
        :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.
        """
        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'


class LoadBalancerListenerReference():
    """
    LoadBalancerListenerReference.

    :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) -> None:
        """
        Initialize a LoadBalancerListenerReference object.

        :param str href: The listener's canonical URL.
        :param str id: The unique identifier for this load balancer listener.
        """
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerReference':
        """Initialize a LoadBalancerListenerReference object from a json dictionary."""
        args = {}
        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, '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 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 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.
    """

    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,
        *,
        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 List[LoadBalancerPoolMemberReference] members: (optional) The
               backend server members of the pool.
        :param LoadBalancerPoolSessionPersistence session_persistence: (optional)
               The session persistence of this pool.
        """
        self.algorithm = algorithm
        self.created_at = created_at
        self.health_monitor = health_monitor
        self.href = href
        self.id = id
        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 '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, '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.
    :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.
        :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.
    :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.
        :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.
    :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.
        :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 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) -> 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.
        """
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberReference':
        """Initialize a LoadBalancerPoolMemberReference object from a json dictionary."""
        args = {}
        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, '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 LoadBalancerPoolMemberTarget():
    """
    The pool member target.

    """

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

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


class LoadBalancerPoolMemberTargetPrototype():
    """
    The pool member target.

    """

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

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['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 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) -> 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.
        """
        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 '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, '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 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 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 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 List[NetworkACLRuleItem] rules: The ordered rules for this network ACL. If
          no rules exist, all traffic will be allowed.
    :attr List[SubnetReference] subnets: The subnets to which this network ACL is
          attached.
    """

    def __init__(self, created_at: datetime, href: str, id: str, name: str,
                 rules: List['NetworkACLRuleItem'],
                 subnets: List['SubnetReference']) -> None:
        """
        Initialize a NetworkACL object.

        :param datetime created_at: The date and time that the network ACL was
               created.
        :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 List[NetworkACLRuleItem] rules: The ordered rules for this network
               ACL. If no rules exist, all traffic will be allowed.
        :param List[SubnetReference] subnets: The subnets to which this network ACL
               is attached.
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.rules = rules
        self.subnets = subnets

    @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 '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 'rules' in _dict:
            args['rules'] = [
                NetworkACLRuleItem.from_dict(x) for x in _dict.get('rules')
            ]
        else:
            raise ValueError(
                'Required property \'rules\' not present in NetworkACL JSON')
        if 'subnets' in _dict:
            args['subnets'] = [
                SubnetReference.from_dict(x) for x in _dict.get('subnets')
            ]
        else:
            raise ValueError(
                'Required property \'subnets\' not present in NetworkACL JSON')
        return cls(**args)

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

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

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

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

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

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


class NetworkACLCollection():
    """
    NetworkACLCollection.

    :attr NetworkACLCollectionFirst first: A 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.
    """

    def __init__(self,
                 first: 'NetworkACLCollectionFirst',
                 limit: int,
                 network_acls: List['NetworkACL'],
                 *,
                 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 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

    @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'))
        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()
        return _dict

    def _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', 'NetworkACLIdentityByHref']))
        raise Exception(msg)


class NetworkACLPatch():
    """
    NetworkACLPatch.

    :attr str name: (optional) The unique user-defined name for this network ACL.
    """

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

        :param str name: (optional) The unique user-defined name for this network
               ACL.
        """
        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 unique user-defined name for this network ACL. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    """

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

        :param str name: (optional) The unique user-defined name for this network
               ACL. 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([
                'NetworkACLPrototypeNetworkACLByRules',
                'NetworkACLPrototypeNetworkACLBySourceNetworkACL'
            ]))
        raise Exception(msg)


class NetworkACLReference():
    """
    NetworkACLReference.

    :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, href: str, id: str, name: str) -> None:
        """
        Initialize a NetworkACLReference object.

        :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.
        """
        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 '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, '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 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.
    """

    def __init__(self,
                 first: 'NetworkACLRuleCollectionFirst',
                 limit: int,
                 rules: List['NetworkACLRuleItem'],
                 *,
                 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 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

    @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'
            )
        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]
        return _dict

    def _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 str destination: (optional) The destination IP address or CIDR block. The
          CIDR block `0.0.0.0/0` applies to all addresses.
    :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 protocol: (optional) The protocol to enforce.
    :attr str source: (optional) The source IP address or CIDR block.  The CIDR
          block `0.0.0.0/0` applies to all addresses.
    """

    def __init__(self,
                 *,
                 action: str = None,
                 before: 'NetworkACLRuleBeforePatch' = None,
                 destination: str = None,
                 direction: str = None,
                 name: str = None,
                 protocol: str = None,
                 source: str = 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 str destination: (optional) The destination IP address or CIDR
               block. The CIDR block `0.0.0.0/0` applies to all addresses.
        :param str direction: (optional) Whether the traffic to be matched is
               `inbound` or `outbound`.
        :param str name: (optional) The user-defined name for this rule. Names must
               be unique within the network ACL the rule resides in.
        :param str protocol: (optional) The protocol to enforce.
        :param str source: (optional) The source IP address or CIDR block.  The
               CIDR block `0.0.0.0/0` applies to all addresses.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP',
                'NetworkACLRulePatchNetworkACLRuleProtocolICMP',
                'NetworkACLRulePatchNetworkACLRuleProtocolAll'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePatch':
        """Initialize a NetworkACLRulePatch 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 'NetworkACLRulePatch'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP',
            'NetworkACLRulePatchNetworkACLRuleProtocolICMP',
            'NetworkACLRulePatchNetworkACLRuleProtocolAll'
        ]))
        raise Exception(msg)

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

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['all'] = 'NetworkACLRulePatchNetworkACLRuleProtocolAll'
        mapping['icmp'] = 'NetworkACLRulePatchNetworkACLRuleProtocolICMP'
        mapping['tcp'] = 'NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP'
        mapping['udp'] = 'NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in NetworkACLRulePatch 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 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 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) -> 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.
        """
        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 '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, '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 NetworkInterface():
    """
    NetworkInterface.

    :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.
          Due to a known issue, the value for this property may be `ACTIVE` instead of
          `available`.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The type of this network interface as it relates to an instance.
    """

    def __init__(self,
                 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 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.
               Due to a known issue, the value for this property may be `ACTIVE` instead
               of
               `available`.
        :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.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 '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, '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.
        Due to a known issue, the value for this property may be `ACTIVE` instead of
        `available`.
        """
        ACTIVE = 'active'
        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 List[NetworkInterface] network_interfaces: Collection of network
          interfaces.
    """

    def __init__(self, network_interfaces: List['NetworkInterface']) -> None:
        """
        Initialize a NetworkInterfaceCollection object.

        :param List[NetworkInterface] network_interfaces: Collection of network
               interfaces.
        """
        self.network_interfaces = network_interfaces

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceCollection':
        """Initialize a NetworkInterfaceCollection 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 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,
                'network_interfaces') and self.network_interfaces is not None:
            _dict['network_interfaces'] = [
                x.to_dict() for x in self.network_interfaces
            ]
        return _dict

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

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

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

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


class NetworkInterfaceInstanceContextReference():
    """
    NetworkInterfaceInstanceContextReference.

    :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') -> 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.
        """
        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 '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, '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 NetworkInterfacePrototype():
    """
    NetworkInterfacePrototype.

    :attr str name: (optional) The user-defined name for this network interface. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str primary_ipv4_address: (optional) The primary IPv4 address. If
          specified, it must be an available address on the network interface's subnet. If
          unspecified, an available address on the subnet will be automatically selected.
    :attr List[SecurityGroupIdentity] security_groups: (optional) Collection of
          security groups.
    :attr SubnetIdentity subnet: The associated subnet.
    """

    def __init__(self,
                 subnet: 'SubnetIdentity',
                 *,
                 name: str = None,
                 primary_ipv4_address: str = None,
                 security_groups: List['SecurityGroupIdentity'] = None) -> None:
        """
        Initialize a NetworkInterfacePrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param str name: (optional) The user-defined name for this network
               interface. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str primary_ipv4_address: (optional) The primary IPv4 address. If
               specified, it must be an available address on the network interface's
               subnet. If unspecified, an available address on the subnet will be
               automatically selected.
        :param List[SecurityGroupIdentity] security_groups: (optional) Collection
               of security groups.
        """
        self.name = name
        self.primary_ipv4_address = primary_ipv4_address
        self.security_groups = security_groups
        self.subnet = subnet

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ipv4_address'
                   ) and self.primary_ipv4_address is not None:
            _dict['primary_ipv4_address'] = self.primary_ipv4_address
        if hasattr(self,
                   'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for x in self.security_groups:
                if isinstance(x, dict):
                    security_groups_list.append(x)
                else:
                    security_groups_list.append(x.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        return _dict

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

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

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

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


class NetworkInterfaceReference():
    """
    NetworkInterfaceReference.

    :attr str 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) -> 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.
        """
        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 '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, '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 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 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, 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 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.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 '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, '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 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 where this public gateway lives.
    """

    def __init__(self, created_at: datetime, crn: str,
                 floating_ip: 'PublicGatewayFloatingIp', href: str, id: str,
                 name: str, 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 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 where this public gateway lives.
        """
        self.created_at = created_at
        self.crn = crn
        self.floating_ip = floating_ip
        self.href = href
        self.id = id
        self.name = name
        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_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_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.
    """

    def __init__(self,
                 first: 'PublicGatewayCollectionFirst',
                 limit: int,
                 public_gateways: List['PublicGateway'],
                 *,
                 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 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

    @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'
            )
        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
            ]
        return _dict

    def _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 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) -> 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.
        """
        self.address = address
        self.crn = crn
        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 '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, '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 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) -> 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.
        """
        self.crn = crn
        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 '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, '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 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 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.
    """

    def __init__(self, href: str, id: 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.
        """
        self.href = href
        self.id = id

    @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'
            )
        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
        return _dict

    def _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: The next hop that packets will be delivered to.
    :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: The next hop that packets will be delivered
               to.
        :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 List[Route] routes: Collection of routes.
    """

    def __init__(self, routes: List['Route']) -> None:
        """
        Initialize a RouteCollection object.

        :param List[Route] routes: Collection of routes.
        """
        self.routes = routes

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

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

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

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

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

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

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


class RouteNextHop():
    """
    RouteNextHop.

    """

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

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


class RouteNextHopPrototype():
    """
    The next hop packets will be routed to.

    """

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

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


class 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 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. Security group
          names must be unique, within the scope of an account.
    :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 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'], 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. Security
               group names must be unique, within the scope of an account.
        :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 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.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 '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, '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 List[SecurityGroup] security_groups: Collection of security groups.
    """

    def __init__(self, security_groups: List['SecurityGroup']) -> None:
        """
        Initialize a SecurityGroupCollection object.

        :param List[SecurityGroup] security_groups: Collection of security groups.
        """
        self.security_groups = security_groups

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

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

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

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

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

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

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


class 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.
          Security group names must be unique, within the scope of an account.
    """

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

        :param str name: (optional) The user-defined name for this security group.
               Security group names must be unique, within the scope of an account.
        """
        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 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. Security group
          names must be unique, within the scope of an account.
    """

    def __init__(self, crn: str, href: str, id: str, name: str) -> 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. Security
               group names must be unique, within the scope of an account.
        """
        self.crn = crn
        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 '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, '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 SecurityGroupRule():
    """
    SecurityGroupRule.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :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: (optional) 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. If omitted, then traffic is allowed from any source (or to any
          source, for outbound rules).
    """

    def __init__(self,
                 direction: str,
                 id: str,
                 *,
                 ip_version: str = None,
                 protocol: str = None,
                 remote: 'SecurityGroupRuleRemote' = None) -> None:
        """
        Initialize a SecurityGroupRule object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str id: The unique identifier for this security group rule.
        :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 SecurityGroupRuleRemote remote: (optional) 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. If omitted, then traffic is allowed 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([
                '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 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 str protocol: (optional) The protocol to enforce.
    :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).
    """

    def __init__(self,
                 *,
                 direction: str = None,
                 ip_version: str = None,
                 protocol: str = None,
                 remote: 'SecurityGroupRuleRemotePatch' = None) -> None:
        """
        Initialize a SecurityGroupRulePatch object.

        :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 str protocol: (optional) The protocol to enforce.
        :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).
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SecurityGroupRulePatchSecurityGroupRuleProtocolAll',
                'SecurityGroupRulePatchSecurityGroupRuleProtocolICMP',
                'SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP'
            ]))
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePatch':
        """Initialize a SecurityGroupRulePatch 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 'SecurityGroupRulePatch'. "
            + "The discriminator value should map to a valid subclass: {1}"
        ).format(", ".join([
            'SecurityGroupRulePatchSecurityGroupRuleProtocolAll',
            'SecurityGroupRulePatchSecurityGroupRuleProtocolICMP',
            'SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP'
        ]))
        raise Exception(msg)

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

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['all'] = 'SecurityGroupRulePatchSecurityGroupRuleProtocolAll'
        mapping['icmp'] = 'SecurityGroupRulePatchSecurityGroupRuleProtocolICMP'
        mapping['tcp'] = 'SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP'
        mapping['udp'] = 'SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP'
        disc_value = _dict.get('protocol')
        if disc_value is None:
            raise ValueError(
                'Discriminator property \'protocol\' not found in SecurityGroupRulePatch 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 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, then traffic will be allowed 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, then traffic will be allowed 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. If omitted, then traffic is allowed 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, then traffic will be allowed 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 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 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 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,
                 ipv4_cidr_block: str,
                 name: str,
                 network_acl: 'NetworkACLReference',
                 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 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 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.ipv4_cidr_block = ipv4_cidr_block
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        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 '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 '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,
                   '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, '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 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.
    """

    def __init__(self,
                 first: 'SubnetCollectionFirst',
                 limit: int,
                 subnets: List['Subnet'],
                 *,
                 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 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

    @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'
            )
        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]
        return _dict

    def _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.
    """

    def __init__(self,
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = 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.
        """
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway

    @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')
        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()
        return _dict

    def _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 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 VPCIdentity vpc: The VPC the subnet is to be a part of.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None) -> None:
        """
        Initialize a SubnetPrototype object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet.
        :param PublicGatewayIdentity public_gateway: (optional) The public gateway
               to handle internet bound traffic for this subnet.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join([
                'SubnetPrototypeSubnetByTotalCount',
                'SubnetPrototypeSubnetByCIDR'
            ]))
        raise Exception(msg)


class SubnetReference():
    """
    SubnetReference.

    :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 name: The user-defined name for this subnet.
    """

    def __init__(self, crn: str, href: str, id: str, name: str) -> 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.
        """
        self.crn = crn
        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 '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, '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 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 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_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 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_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_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_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 belongs
          to.
    """

    def __init__(self, ip: 'IP', zone: 'ZoneReference') -> None:
        """
        Initialize a VPCCSESourceIP object.

        :param IP ip: The Cloud Service Endpoint source IP address for this zone.
        :param ZoneReference zone: The zone this Cloud Service Endpoint source IP
               belongs to.
        """
        self.ip = ip
        self.zone = zone

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

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

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

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

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

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

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


class VPCCollection():
    """
    VPCCollection.

    :attr VPCCollectionFirst first: A 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 List[VPC] vpcs: Collection of VPCs.
    """

    def __init__(self,
                 first: 'VPCCollectionFirst',
                 limit: 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 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.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 '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, '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 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) -> 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.
        """
        self.crn = crn
        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 '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, '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 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(['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(['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.
        """
        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

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPatch':
        """Initialize a VPNGatewayConnectionPatch 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')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPatch object from 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
        return _dict

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

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

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

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


class VPNGatewayConnectionPeerCIDRs():
    """
    VPNGatewayConnectionPeerCIDRs.

    :attr List[str] peer_cidrs: (optional) A collection of peer CIDRs for this
          resource.
    """

    def __init__(self, *, peer_cidrs: List[str] = None) -> None:
        """
        Initialize a VPNGatewayConnectionPeerCIDRs object.

        :param List[str] peer_cidrs: (optional) A collection of peer CIDRs for this
               resource.
        """
        self.peer_cidrs = peer_cidrs

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

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

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

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

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

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

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


class 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([
                'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype'
            ]))
        raise Exception(msg)


class VPNGatewayConnectionReference():
    """
    VPNGatewayConnectionReference.

    :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) -> 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.
        """
        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 '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, '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 VPNGatewayMember():
    """
    VPNGatewayMember.

    :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) -> 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.
        """
        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 '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, '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(['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[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,
            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[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.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 '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,
                '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'
        UNUSABLE = 'unusable'
        PENDING_DELETION = 'pending_deletion'


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 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',
                 *,
                 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 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.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 '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, '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 VolumeAttachmentReferenceVolumeContext():
    """
    VolumeAttachmentReferenceVolumeContext.

    :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,
                 href: str,
                 id: str,
                 instance: 'InstanceReference',
                 name: str,
                 type: str,
                 *,
                 device: 'VolumeAttachmentDevice' = None) -> None:
        """
        Initialize a VolumeAttachmentReferenceVolumeContext object.

        :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 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.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 '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, '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 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([
                '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 EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr 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 location of the volume.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 zone: 'ZoneIdentity',
                 *,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 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 location of the volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        :param 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, 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, 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 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) -> 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.
        """
        self.crn = crn
        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 '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, '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 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 belongs to.
    :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 belongs to.
        :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 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 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 FloatingIPByTargetNetworkInterfaceIdentity target: The network interface
          this floating IP is to be bound to.
    """

    def __init__(self,
                 target: 'FloatingIPByTargetNetworkInterfaceIdentity',
                 *,
                 name: str = 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.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        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 '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, '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 ZoneIdentity zone: The identity of the zone to provision a floating IP in.
    """

    def __init__(self, zone: 'ZoneIdentity', *, name: str = None) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByZone object.

        :param ZoneIdentity zone: The identity of the zone to provision a floating
               IP in.
        :param str name: (optional) The unique user-defined name for this floating
               IP. If unspecified, the name will be a hyphenated list of randomly-selected
               words.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        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 '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, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

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

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

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

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


class FloatingIPTargetNetworkInterfaceReference(FloatingIPTarget):
    """
    FloatingIPTargetNetworkInterfaceReference.

    :attr str 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) -> 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.
        """
        # pylint: disable=super-init-not-called
        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 '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, '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 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) -> 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.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        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 '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, '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 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 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) -> 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)
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.file = file
        self.operating_system = operating_system

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

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

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

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

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

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

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


class InstanceProfileBandwidthDependent(InstanceProfileBandwidth):
    """
    The total bandwidth shared across the network interfaces of an instance with this
    profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

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

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

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

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

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

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

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

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

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

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        DEPENDENT = 'dependent'


class InstanceProfileBandwidthEnum(InstanceProfileBandwidth):
    """
    The permitted total bandwidth values (in megabits per second) shared across the
    network interfaces of an instance with this profile.

    :attr 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 of
    an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(self, type: str, value: int) -> None:
        """
        Initialize a InstanceProfileBandwidthFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

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

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

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

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

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

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

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

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """
        FIXED = 'fixed'


class InstanceProfileBandwidthRange(InstanceProfileBandwidth):
    """
    The permitted total bandwidth range (in megabits per second) shared across the network
    interfaces of an instance with this profile.

    :attr 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 InstanceProfileIdentityByCRN(InstanceProfileIdentity):
    """
    InstanceProfileIdentityByCRN.

    :attr str crn: The CRN for this virtual server instance profile.
    """

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

        :param str crn: The CRN for this virtual server instance profile.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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


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 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 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 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 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 identity of the zone to provision the virtual
          server instance in.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        keys: List['KeyIdentity'] = None,
        name: str = None,
        network_interfaces: List['NetworkInterfacePrototype'] = 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 identity of the zone to provision the virtual
               server instance 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 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 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.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 '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, '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 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 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) -> 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.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        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 '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, '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 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 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) -> 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.
        """
        # pylint: disable=super-init-not-called
        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 '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, '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 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 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 unique user-defined name for this network ACL. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr List[NetworkACLRulePrototypeNetworkACLContext] rules: (optional) Array of
          prototype objects for rules to create along with this network ACL. If
          unspecified, rules will be created to allow all traffic.
    """

    def __init__(
            self,
            *,
            name: str = None,
            rules: List['NetworkACLRulePrototypeNetworkACLContext'] = None
    ) -> None:
        """
        Initialize a NetworkACLPrototypeNetworkACLByRules object.

        :param str name: (optional) The unique user-defined name for this network
               ACL. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param List[NetworkACLRulePrototypeNetworkACLContext] rules: (optional)
               Array of prototype objects for rules to create along with this network ACL.
               If unspecified, rules will be created to allow all traffic.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        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 '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, '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 unique user-defined name for this network ACL. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr NetworkACLIdentity source_network_acl: Network ACL to copy rules from.
    """

    def __init__(self,
                 source_network_acl: 'NetworkACLIdentity',
                 *,
                 name: str = None) -> None:
        """
        Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object.

        :param NetworkACLIdentity source_network_acl: Network ACL to copy rules
               from.
        :param str name: (optional) The unique user-defined name for this network
               ACL. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        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 '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,
                '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 port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int 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,
                 port_max: int = None,
                 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 port_max: (optional) The inclusive upper bound of TCP/UDP
               destination port range.
        :param int 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.port_max = port_max
        self.port_min = 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 '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 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, '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
        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 NetworkACLRulePatchNetworkACLRuleProtocolAll(NetworkACLRulePatch):
    """
    NetworkACLRulePatchNetworkACLRuleProtocolAll.

    :attr str action: (optional) Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePatch before: (optional)
    :attr str destination: (optional) The destination IP address or CIDR block. The
          CIDR block `0.0.0.0/0` applies to all addresses.
    :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 str protocol: The protocol to enforce.
    """

    def __init__(self,
                 protocol: str,
                 *,
                 action: str = None,
                 before: 'NetworkACLRuleBeforePatch' = None,
                 destination: str = None,
                 direction: str = None,
                 name: str = None,
                 source: str = None) -> None:
        """
        Initialize a NetworkACLRulePatchNetworkACLRuleProtocolAll object.

        :param str protocol: The protocol to enforce.
        :param str action: (optional) Whether to allow or deny matching traffic.
        :param NetworkACLRuleBeforePatch before: (optional)
        :param str destination: (optional) The destination IP address or CIDR
               block. The CIDR block `0.0.0.0/0` applies to all addresses.
        :param str direction: (optional) Whether the traffic to be matched is
               `inbound` or `outbound`.
        :param str 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.
        """
        # 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) -> 'NetworkACLRulePatchNetworkACLRuleProtocolAll':
        """Initialize a NetworkACLRulePatchNetworkACLRuleProtocolAll 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 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        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 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError(
                'Required property \'protocol\' not present in NetworkACLRulePatchNetworkACLRuleProtocolAll JSON'
            )
        return cls(**args)

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

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

    def __ne__(self,
               other: 'NetworkACLRulePatchNetworkACLRuleProtocolAll') -> 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 NetworkACLRulePatchNetworkACLRuleProtocolICMP(NetworkACLRulePatch):
    """
    NetworkACLRulePatchNetworkACLRuleProtocolICMP.

    :attr str action: (optional) Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePatch before: (optional)
    :attr str destination: (optional) The destination IP address or CIDR block. The
          CIDR block `0.0.0.0/0` applies to all addresses.
    :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 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,
                 protocol: str,
                 *,
                 action: str = None,
                 before: 'NetworkACLRuleBeforePatch' = None,
                 destination: str = None,
                 direction: str = None,
                 name: str = None,
                 source: str = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a NetworkACLRulePatchNetworkACLRuleProtocolICMP object.

        :param str protocol: The protocol to enforce.
        :param str action: (optional) Whether to allow or deny matching traffic.
        :param NetworkACLRuleBeforePatch before: (optional)
        :param str destination: (optional) The destination IP address or CIDR
               block. The CIDR block `0.0.0.0/0` applies to all addresses.
        :param str direction: (optional) Whether the traffic to be matched is
               `inbound` or `outbound`.
        :param str 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 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) -> 'NetworkACLRulePatchNetworkACLRuleProtocolICMP':
        """Initialize a NetworkACLRulePatchNetworkACLRuleProtocolICMP 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 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        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 '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 NetworkACLRulePatchNetworkACLRuleProtocolICMP JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

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

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

    def __ne__(self,
               other: 'NetworkACLRulePatchNetworkACLRuleProtocolICMP') -> 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 NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP(NetworkACLRulePatch):
    """
    NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP.

    :attr str action: (optional) Whether to allow or deny matching traffic.
    :attr NetworkACLRuleBeforePatch before: (optional)
    :attr str destination: (optional) The destination IP address or CIDR block. The
          CIDR block `0.0.0.0/0` applies to all addresses.
    :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 port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int 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,
                 protocol: str,
                 *,
                 action: str = None,
                 before: 'NetworkACLRuleBeforePatch' = None,
                 destination: str = None,
                 direction: str = None,
                 name: str = None,
                 source: str = None,
                 port_max: int = None,
                 port_min: int = None,
                 source_port_max: int = None,
                 source_port_min: int = None) -> None:
        """
        Initialize a NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP object.

        :param str protocol: The protocol to enforce.
        :param str action: (optional) Whether to allow or deny matching traffic.
        :param NetworkACLRuleBeforePatch before: (optional)
        :param str destination: (optional) The destination IP address or CIDR
               block. The CIDR block `0.0.0.0/0` applies to all addresses.
        :param str direction: (optional) Whether the traffic to be matched is
               `inbound` or `outbound`.
        :param str 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 port_max: (optional) The inclusive upper bound of TCP/UDP
               destination port range.
        :param int 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.port_max = port_max
        self.port_min = 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) -> 'NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP 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 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        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 '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 NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP 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 NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP object from 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, '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
        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 NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(
            self,
            other: 'NetworkACLRulePatchNetworkACLRuleProtocolTCPUDP') -> 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 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 port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int 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,
                 port_max: int = None,
                 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 port_max: (optional) The inclusive upper bound of TCP/UDP
               destination port range.
        :param int 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.port_max = port_max
        self.port_min = 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 '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 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, '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
        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 port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int 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,
                 port_max: int = None,
                 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 port_max: (optional) The inclusive upper bound of TCP/UDP
               destination port range.
        :param int 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.port_max = port_max
        self.port_min = 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 '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 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, '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
        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 port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int 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,
                 port_max: int = None,
                 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 port_max: (optional) The inclusive upper bound of TCP/UDP
               destination port range.
        :param int 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.port_max = port_max
        self.port_min = 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 '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 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, '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
        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.
    """

    def __init__(self, *, name: str = 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.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @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')
        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
        return _dict

    def _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 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 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 SecurityGroupRulePatchSecurityGroupRuleProtocolAll(
        SecurityGroupRulePatch):
    """
    When `protocol` is `all`, then it's invalid to specify `port_min`, `port_max`, `type`
    or
    `code`.

    :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 SecurityGroupRuleRemotePatch remote: (optional)
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 protocol: str,
                 *,
                 direction: str = None,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemotePatch' = None) -> None:
        """
        Initialize a SecurityGroupRulePatchSecurityGroupRuleProtocolAll object.

        :param str protocol: The protocol to enforce.
        :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 SecurityGroupRuleRemotePatch 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
    ) -> 'SecurityGroupRulePatchSecurityGroupRuleProtocolAll':
        """Initialize a SecurityGroupRulePatchSecurityGroupRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        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 SecurityGroupRulePatchSecurityGroupRuleProtocolAll JSON'
            )
        return cls(**args)

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

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

    def __ne__(
            self, other: 'SecurityGroupRulePatchSecurityGroupRuleProtocolAll'
    ) -> 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 SecurityGroupRulePatchSecurityGroupRuleProtocolICMP(
        SecurityGroupRulePatch):
    """
    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: (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 SecurityGroupRuleRemotePatch 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,
                 protocol: str,
                 *,
                 direction: str = None,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemotePatch' = None,
                 code: int = None,
                 type: int = None) -> None:
        """
        Initialize a SecurityGroupRulePatchSecurityGroupRuleProtocolICMP object.

        :param str protocol: The protocol to enforce.
        :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 SecurityGroupRuleRemotePatch 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
    ) -> 'SecurityGroupRulePatchSecurityGroupRuleProtocolICMP':
        """Initialize a SecurityGroupRulePatchSecurityGroupRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        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 SecurityGroupRulePatchSecurityGroupRuleProtocolICMP JSON'
            )
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

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

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

    def __ne__(
            self, other: 'SecurityGroupRulePatchSecurityGroupRuleProtocolICMP'
    ) -> 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 SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP(
        SecurityGroupRulePatch):
    """
    If `protocol` is either `tcp` or `udp`, then the rule may also contain `port_min` and
    `port_max`. Either both should be set, or neither. When neither is set then traffic is
    allowed on all ports. For a single port, set both to the same value.

    :attr str direction: (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 SecurityGroupRuleRemotePatch 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,
                 protocol: str,
                 *,
                 direction: str = None,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemotePatch' = None,
                 port_max: int = None,
                 port_min: int = None) -> None:
        """
        Initialize a SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP object.

        :param str protocol: The protocol to enforce.
        :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 SecurityGroupRuleRemotePatch 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
    ) -> 'SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP':
        """Initialize a SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        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 SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP JSON'
            )
        return cls(**args)

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

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

    def __ne__(
            self, other: 'SecurityGroupRulePatchSecurityGroupRuleProtocolTCPUDP'
    ) -> 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 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 should be set, or neither. When neither is set then traffic is
    allowed on all ports. For a single port, set both to the same value.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this field, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr 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 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. Security group
          names must be unique, within the scope of an account.
    """

    def __init__(self, crn: str, href: str, id: str, name: str) -> 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. Security
               group names must be unique, within the scope of an account.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        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 '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, '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 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: (optional)
    :attr str protocol: The protocol to enforce.
    """

    def __init__(self,
                 direction: str,
                 id: str,
                 protocol: str,
                 *,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemote' = None) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to enforce, either `inbound`
               or `outbound`.
        :param str id: The unique identifier for this security group rule.
        :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 SecurityGroupRuleRemote remote: (optional)
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        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 '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')
        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, '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 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: (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,
                 id: str,
                 protocol: str,
                 *,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemote' = 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 id: The unique identifier for this security group rule.
        :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 SecurityGroupRuleRemote 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.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 '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')
        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, '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 should be set, or neither. When neither is set then traffic is
    allowed on all ports. For a single port, set both to the same value.

    :attr str direction: The direction of traffic to enforce, either `inbound` or
          `outbound`.
    :attr str 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: (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,
                 id: str,
                 protocol: str,
                 *,
                 ip_version: str = None,
                 remote: 'SecurityGroupRuleRemote' = 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 id: The unique identifier for this security group rule.
        :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 SecurityGroupRuleRemote 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.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 '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')
        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, '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 SubnetIdentityByCRN(SubnetIdentity):
    """
    SubnetIdentityByCRN.

    :attr str crn: The CRN for this subnet.
    """

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

        :param str crn: The CRN for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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

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

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

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


class SubnetIdentityByHref(SubnetIdentity):
    """
    SubnetIdentityByHref.

    :attr str href: The URL for this subnet.
    """

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

        :param str href: The URL for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.href = href

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

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

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

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

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

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

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


class SubnetIdentityById(SubnetIdentity):
    """
    SubnetIdentityById.

    :attr str id: The unique identifier for this subnet.
    """

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

        :param str id: The unique identifier for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id

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

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

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

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

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

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

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


class SubnetPrototypeSubnetByCIDR(SubnetPrototype):
    """
    SubnetPrototypeSubnetByCIDR.

    :attr str name: (optional) The user-defined name for this subnet. Names must be
          unique within the VPC the subnet resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr NetworkACLIdentity network_acl: (optional) The network ACL to use for this
          subnet. 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 VPCIdentity vpc: The VPC the subnet is to be a part of.
    :attr str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
          format. The prefix length of the subnet's CIDR must be between `/8` (16,777,216
          addresses) and `/29` (8 addresses). The IPv4 range of the subnet's CIDR must
          fall within an existing address prefix in the VPC. The subnet will be created in
          the zone of the address prefix that contains the IPv4 CIDR. If zone is
          specified, it must match the zone of the address prefix that contains the
          subnet's IPv4 CIDR.
    :attr ZoneIdentity zone: (optional) The zone the subnet is to reside in.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 ipv4_cidr_block: str,
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None,
                 zone: 'ZoneIdentity' = None) -> None:
        """
        Initialize a SubnetPrototypeSubnetByCIDR object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
               format. The prefix length of the subnet's CIDR must be between `/8`
               (16,777,216 addresses) and `/29` (8 addresses). The IPv4 range of the
               subnet's CIDR must fall within an existing address prefix in the VPC. The
               subnet will be created in the zone of the address prefix that contains the
               IPv4 CIDR. If zone is specified, it must match the zone of the address
               prefix that contains the subnet's IPv4 CIDR.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet. 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 ZoneIdentity zone: (optional) The zone the subnet is to reside in.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.vpc = vpc
        self.ipv4_cidr_block = ipv4_cidr_block
        self.zone = zone

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, '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 SubnetPrototypeSubnetByTotalCount(SubnetPrototype):
    """
    SubnetPrototypeSubnetByTotalCount.

    :attr str name: (optional) The user-defined name for this subnet. Names must be
          unique within the VPC the subnet resides in. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr NetworkACLIdentity network_acl: (optional) The network ACL to use for this
          subnet. 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 VPCIdentity vpc: The VPC the subnet is to be a part of.
    :attr int total_ipv4_address_count: The total number of IPv4 addresses required.
          Must be a power of 2. The VPC must have a default address prefix in the
          specified zone, and that prefix must have a free CIDR range with at least this
          number of addresses.
    :attr ZoneIdentity zone: The zone the subnet is to reside in.
    """

    def __init__(self,
                 vpc: 'VPCIdentity',
                 total_ipv4_address_count: int,
                 zone: 'ZoneIdentity',
                 *,
                 name: str = None,
                 network_acl: 'NetworkACLIdentity' = None,
                 public_gateway: 'PublicGatewayIdentity' = None) -> None:
        """
        Initialize a SubnetPrototypeSubnetByTotalCount object.

        :param VPCIdentity vpc: The VPC the subnet is to be a part of.
        :param int total_ipv4_address_count: The total number of IPv4 addresses
               required. Must be a power of 2. The VPC must have a default address prefix
               in the specified zone, and that prefix must have a free CIDR range with at
               least this number of addresses.
        :param ZoneIdentity zone: The zone the subnet is to reside in.
        :param str name: (optional) The user-defined name for this subnet. Names
               must be unique within the VPC the subnet resides in. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet. 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.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.vpc = vpc
        self.total_ipv4_address_count = total_ipv4_address_count
        self.zone = zone

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, '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 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 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 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 VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext(
        VolumeAttachmentVolumePrototypeInstanceContext):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext.

    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr 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',
                 *,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None,
                 name: str = None) -> None:
        """
        Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        :param 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 EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr 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 location of the 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.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 zone: 'ZoneIdentity',
                 capacity: int,
                 *,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None,
                 name: str = None,
                 resource_group: 'ResourceGroupIdentity' = None) -> None:
        """
        Initialize a VolumePrototypeVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The profile to use for this volume.
        :param ZoneIdentity zone: The location of the volume.
        :param int capacity: The capacity of the volume in gigabytes. 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, 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.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.encryption_key = encryption_key
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.zone = zone
        self.capacity = capacity

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeVolumeByCapacity':
        """Initialize a VolumePrototypeVolumeByCapacity object from a json dictionary."""
        args = {}
        if '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 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'
            )
        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, '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()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        return _dict

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

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

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

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


class ZoneIdentityByHref(ZoneIdentity):
    """
    ZoneIdentityByHref.

    :attr str href: The URL for this zone.
    """

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

        :param str href: The URL for this zone.
        """
        # pylint: disable=super-init-not-called
        self.href = href

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

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

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

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

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

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

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


class ZoneIdentityByName(ZoneIdentity):
    """
    ZoneIdentityByName.

    :attr str name: The 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 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 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 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 VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity(
        VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext
):
    """
    VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity.

    :attr EncryptionKeyIdentity encryption_key: (optional) The identity of the root
          key to use to wrap the data encryption key for the volume.
          If this property is not provided, the `encryption` type for the volume will be
          `provider_managed`.
    :attr int iops: (optional) The bandwidth for the volume.
    :attr 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.
    """

    def __init__(self,
                 profile: 'VolumeProfileIdentity',
                 capacity: int,
                 *,
                 encryption_key: 'EncryptionKeyIdentity' = None,
                 iops: int = None,
                 name: str = 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 EncryptionKeyIdentity encryption_key: (optional) The identity of the
               root key to use to wrap the data encryption key for the volume.
               If this property is not provided, the `encryption` type for the volume will
               be
               `provider_managed`.
        :param int iops: (optional) The bandwidth for the volume.
        :param str name: (optional) The unique user-defined name for this volume.
        """
        # pylint: disable=super-init-not-called
        self.encryption_key = encryption_key
        self.iops = iops
        self.name = name
        self.profile = profile
        self.capacity = capacity

    @classmethod
    def from_dict(
        cls, _dict: Dict
    ) -> 'VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity':
        """Initialize a VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from a json dictionary."""
        args = {}
        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 VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON'
            )
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError(
                'Required property \'capacity\' not present in VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON'
            )
        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, '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()
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        return _dict

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

    def __str__(self) -> str:
        """Return a `str` version of this 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
